Beispiel #1
0
        /// <summary>
        /// This method calculates the type of eye movement given a new point
        /// </summary>
        /// <param name="newPoint">New point</param>
        public void CalculateEyeMovement(GTPoint newPoint)
        {
            long time = DateTime.UtcNow.Ticks/TimeSpan.TicksPerMillisecond;
            AddNewPoint(newPoint, time);

            if (recentPoints.Count > 1)
            {
                if (Operations.GetMaxDistanceOnWindow(recentPoints) < Settings.Instance.EyeMovement.MaxDispersion)
                {
                    CalculateVelocity();
                    if (velocities[velocities.Count - 1] > Settings.Instance.EyeMovement.MaxAngularSpeed)
                        eyeMovementState = EyeMovementStateEnum.NoFixation;
                    else
                        eyeMovementState = EyeMovementStateEnum.Fixation;
                }
                else
                    eyeMovementState = EyeMovementStateEnum.NoFixation;
            }
            else
                eyeMovementState = EyeMovementStateEnum.NoFixation;

            if (eyeMovementState == EyeMovementStateEnum.NoFixation)
            {
                if (TrackDB.Instance.GetLastSample().EyeMovement == EyeMovementStateEnum.Fixation)
                {
                    recentPoints.Clear();
                    Settings.Instance.EyeMovement.WindowSize = 2;
                    AddNewPoint(newPoint, time);
                }
            }
            else
                Settings.Instance.EyeMovement.WindowSize = Math.Min(Settings.Instance.EyeMovement.WindowSize,
                                                                     Settings.Instance.EyeMovement.MaxWindowSize);
        }
        /// <summary>
        /// Detect two glints in a grayscale image.
        /// This method will select the two glints closest to the initial location
        /// </summary>
        /// <param name="inputImage">Input image in grayscale</param>
        /// <param name="glintThreshold">Gray level to threshold the image</param>
        /// <param name="minGlintSize">Minimum glint size allowed (radius in pixels)</param>
        /// <param name="maxGlintSize">Maximum glint size allowed (radius in pixels)</param>
        /// <param name="initialLocation">Select the two glints closest this parameter</param>
        /// <returns>True if glint(s) detected, false if not</returns>
        public bool DetectTwoGlints(Image<Gray, byte> inputImage, int glintThreshold,
                                    int minGlintSize, int maxGlintSize, GTPoint initialLocation)
        {
            GlintThreshold = glintThreshold;
            MinGlintSize = minGlintSize;
            MaxGlintSize = 3*maxGlintSize;

            bool foundGlints = false;

            // We get the blobs in the input image given the threshold (minWidth, maxWidth)
            blobs = blobDetector.DetectBlobs(inputImage, glintThreshold, MinGlintSize, MaxGlintSize, true);
            int unfilteredCount = blobs.Count;
            double unfilteredArea = blobs.TotalArea;

            // Filter out exterior blobs
            blobs.EliminateExteriorBlobs();

            if (blobDetector.IsFiltering == false) // Not using AForger filtering
                blobs.FilterByArea(MinGlintSize, MaxGlintSize);

            if (blobs.Count > 1)
            {
                blobs.FilterByDistance(initialLocation, 2);
                glintData.Glints = new GlintConfiguration(blobs);
                // store blobcount for autotune
                glintData.Glints.UnfilteredCount = unfilteredCount;
                glintData.Glints.UnfilteredTotalArea = unfilteredArea;

                if (glintData.Glints.Count > 0)
                    foundGlints = true;
            }

            return foundGlints;
        }
Beispiel #3
0
        public GlintConfiguration(Blob blob)
        {
            count = 1;
            centers = new GTPoint[1];
            blobs.BlobDir[0] = blob;

            centers[0] = new GTPoint(blob.CenterOfGravity.X, blob.CenterOfGravity.Y);
        }
Beispiel #4
0
        /// <summary>
        /// Order any 4 points
        /// </summary>
        /// <param name="points">Array of 4 points</param>
        /// <returns>Ordered array of the 4 points</returns>
        static public GTPoint[] OrderPoints(GTPoint[] points)
        {
            int N = 4;

            GTPoint[] orderedPoints = new GTPoint[N];
            GTPoint   center        = new GTPoint();

            if (points.Length != N)
            {
                Console.WriteLine("error ordering 4 glints");
            }
            else
            {
                center = Operations.Mean(points);
                double[] distances = new double[N - 1];
                for (int i = 0; i < N; i++)
                {
                    if (points[i].X <= center.X && points[i].Y <= center.Y)
                    {
                        orderedPoints[0] = points[i];
                    }
                    else if (points[i].X >= center.X && points[i].Y <= center.Y)
                    {
                        orderedPoints[1] = points[i];
                    }
                    else if (points[i].X >= center.X && points[i].Y >= center.Y)
                    {
                        orderedPoints[2] = points[i];
                    }
                    else if (points[i].X <= center.X && points[i].Y >= center.Y)
                    {
                        orderedPoints[3] = points[i];
                    }
                }

                try
                {
                    for (int i = 0; i < N; i++)
                    {
                        if (orderedPoints[i] == null)
                        {
                            //Console.WriteLine("Incorrect 4 points detected");
                            orderedPoints = new GTPoint[1];
                            return(orderedPoints);
                        }
                    }
                }
                catch
                {
                    //Console.WriteLine("Exception ordering points");
                    orderedPoints = new GTPoint[1];
                }
            }

            return(orderedPoints);
        }
        /// <summary>
        /// Converts a Matrix of points into an array of GTPoints
        /// </summary>
        /// <param name="pointsMatrix">Nx2 matrix, with first column being X coordinate
        /// and second column being Y coordinate</param>
        /// <returns>Array of GTpoints</returns>
        public static GTPoint[] ConvertToArray(Matrix <double> pointsMatrix)
        {
            var pointsArray = new GTPoint[pointsMatrix.Rows];

            for (int i = 0; i < pointsMatrix.Rows; i++)
            {
                pointsArray[i] = new GTPoint(pointsMatrix[i, 0], pointsMatrix[i, 1]);
            }

            return(pointsArray);
        }
Beispiel #6
0
 // Copy constructur
 internal Blob(Blob source)
 {
     // copy everything except image
     id = source.id;
     rect = source.rect;
     cog = source.cog;
     area = source.area;
     fullness = source.fullness;
     colorMean = source.colorMean;
     colorStdDev = source.colorStdDev;
 }
Beispiel #7
0
        public GlintConfiguration(int numGlints)
        {
            count = numGlints;
            centers = new GTPoint[numGlints];
            blobs = new Blobs();

            for (int i = 0; i < numGlints; i++)
            {
                centers[i] = new GTPoint();
                blobs.BlobDir[i] = new Blob();
            }
        }
Beispiel #8
0
        public GlintConfiguration(GlintConfiguration src)
        {
            count = src.Count;
            centers = new GTPoint[count];
            blobs = new Blobs();

            for (int i = 0; i < count; i++)
            {
                centers[i] = new GTPoint(src.centers[i]);
                blobs.BlobDir[i] = new Blob();
                blobs.BlobDir[i] = src.blobs.BlobDir.ElementAt(i).Value;
            }
        }
        /// <summary>
        /// Mean GTPoint of an array of GTPoints
        /// </summary>
        /// <param name="points">Array of GTPoints</param>
        /// <returns>GTPoint containing the mean</returns>
        public static GTPoint Mean(GTPoint[] points)
        {
            double x = 0;
            double y = 0;

            for (int i = 0; i < points.Length; i++)
            {
                x = x + points[i].X;
                y = y + points[i].Y;
            }

            return new GTPoint(x/points.Length, y/points.Length);
        }
Beispiel #10
0
        /// <summary>
        /// Smooth method. Call this method when we get a new
        /// sample and it will return the smoothed coordinates
        /// </summary>
        /// <param name="newPoint">New gazed point</param>
        /// <returns>Smoothed point</returns>
        public GTPoint Smooth(GTPoint newPoint)
        {
            GTPoint smoothedPoint;

            if (data.Count < numberOfSamples)
                data.Add(newPoint);
            else
            {
                data.RemoveAt(0);
                data.Add(newPoint);
            }

            smoothedPoint = Operations.Mean(data.ToArray());

            return smoothedPoint;
        }
Beispiel #11
0
        public static double GetMaxDistanceOnWindow(List <GTPoint> data)
        {
            GTPoint centroid    = Mean(data.ToArray());
            int     maxDistance = 150;

            double maxDist = 0;
            double dist    = 0;

            for (int i = 0; i < data.Count; i++)
            {
                dist = Distance(centroid, data[i]);
                if (dist > maxDistance)
                {
                    maxDist = dist;
                }
            }

            return(maxDist);
        }
Beispiel #12
0
        public void CalculateAngleDegreesTest()
        {
            // Can be used for testing to make sure N-Unit is responding properly
            Assert.IsTrue( true, "Hello World" );

            // Check angle between two simple points
            GTPoint gtPoint1 = new GTPoint( 1.0D, 1.0D );
            GTPoint gtPoint2 = new GTPoint( 2.0D, 2.0D );
            Assert.AreEqual( 45.0D, Operations.CalculateAngle( gtPoint1, gtPoint2 ), UnitTestSettings.DOUBLE_COMPARISON_TOLERANCE );

            // Now create the same GTPoints via two System.Drawing.Point objects and recheck the angles found
            System.Drawing.Point drawingPoint1 = new System.Drawing.Point( 1, 1 );
            System.Drawing.Point drawingPoint2 = new System.Drawing.Point( 2, 2 );
            Assert.AreEqual( 45.0D, Operations.CalculateAngle( drawingPoint1, drawingPoint2 ), UnitTestSettings.DOUBLE_COMPARISON_TOLERANCE );

            // Now create the same GTPoints via two System.Windows.Point objects and recheck the angles found
            System.Windows.Point windowsP1 = new System.Windows.Point( 1, 1 );
            System.Windows.Point windowsP2 = new System.Windows.Point( 2, 2 );
            Assert.AreEqual( 45.0D, Operations.CalculateAngle( windowsP1, windowsP2 ), UnitTestSettings.DOUBLE_COMPARISON_TOLERANCE );
        }
Beispiel #13
0
        public void CalculateAngleDegreesTest()
        {
            // Can be used for testing to make sure N-Unit is responding properly
            Assert.IsTrue(true, "Hello World");

            // Check angle between two simple points
            GTPoint gtPoint1 = new GTPoint(1.0D, 1.0D);
            GTPoint gtPoint2 = new GTPoint(2.0D, 2.0D);

            Assert.AreEqual(45.0D, Operations.CalculateAngle(gtPoint1, gtPoint2), UnitTestSettings.DOUBLE_COMPARISON_TOLERANCE);

            // Now create the same GTPoints via two System.Drawing.Point objects and recheck the angles found
            System.Drawing.Point drawingPoint1 = new System.Drawing.Point(1, 1);
            System.Drawing.Point drawingPoint2 = new System.Drawing.Point(2, 2);
            Assert.AreEqual(45.0D, Operations.CalculateAngle(drawingPoint1, drawingPoint2), UnitTestSettings.DOUBLE_COMPARISON_TOLERANCE);

            // Now create the same GTPoints via two System.Windows.Point objects and recheck the angles found
            System.Windows.Point windowsP1 = new System.Windows.Point(1, 1);
            System.Windows.Point windowsP2 = new System.Windows.Point(2, 2);
            Assert.AreEqual(45.0D, Operations.CalculateAngle(windowsP1, windowsP2), UnitTestSettings.DOUBLE_COMPARISON_TOLERANCE);
        }
Beispiel #14
0
        /// <summary>
        /// Detect glints in a grayscale image.
        /// This method will select the blob closest to coordinates of initialLocation 
        /// that has a lower y coordinate (i.e., corresponds to having the light source
        /// above the screen)
        /// </summary>
        /// <param name="inputImage">Input image in grayscale</param>
        /// <param name="glintThreshold">Gray level to threshold the image</param>
        /// <param name="minGlintSize">Minimum glint size allowed (radius in pixels)</param>
        /// <param name="maxGlintSize">Maximum glint size allowed (radius in pixels)</param>
        /// <param name="initialLocation">Select the glint closest to this parameter</param>
        /// <returns>True if glint detected, true otherwise</returns>
        public bool DetectGlintAbove(Image<Gray, byte> inputImage, int glintThreshold,
                                     int minGlintSize, int maxGlintSize, GTPoint initialLocation)
        {
            bool foundGlints = false;

            GlintThreshold = glintThreshold;
            MinGlintSize = minGlintSize;
            MaxGlintSize = maxGlintSize;

            var min = (int) Math.Round(Math.PI*Math.Pow(minGlintSize, 2));
            var max = (int) Math.Round(Math.PI*Math.Pow(maxGlintSize, 2));

            // We get the blobs in the input image given the threshold
            blobs = blobDetector.DetectBlobs(inputImage, glintThreshold, min, max, true);

            // store blobcount for autotune
            glintData.Glints.UnfilteredCount = blobs.Count;
            glintData.Glints.UnfilteredTotalArea = blobs.TotalArea;

            // Filter out exterior blobs
            if (blobs.Count > 1)
                blobs.EliminateExteriorBlobs();

            if (blobDetector.IsFiltering == false) // Not using AForger filtering
                blobs.FilterByArea(min, max);

            // Eliminate blobs below initialLocation (pupil center)
            blobs.FilterByLocation(initialLocation, 1, 1);

            if (blobs.Count > 1)
                blobs.FilterByDistance(initialLocation);

            if (blobs.Count > 0)
            {
                glintData.Glints = new GlintConfiguration(blobs);
                foundGlints = true;
            }

            return foundGlints;
        }
        /// <summary>
        /// This method calculates the average of the estimated gazed coordinates
        /// (once calibration is finished)
        /// </summary>
        public void CalculateAverageCoords()
        {
            var avgLeft = new GTPoint();
            var avgRight = new GTPoint();
            var varianceLeft = new GTPoint();
            var varianceRight = new GTPoint();

            // Left eye
            if (estimatedGazeCoordinatesLeft.Count > 0)
            {
                avgLeft = Operations.Mean(estimatedGazeCoordinatesLeft.ToArray());
                meanGazeCoordinatesLeft.X = (int) avgLeft.X;
                meanGazeCoordinatesLeft.Y = (int) avgLeft.Y;
                varianceLeft = Operations.Variance(estimatedGazeCoordinatesLeft.ToArray());
                stdDeviationGazeCoordinatesLeft = Math.Sqrt(varianceLeft.X + varianceLeft.Y);
            }
            else
            {
                meanGazeCoordinatesLeft.X = 0;
                meanGazeCoordinatesLeft.Y = 0;
                stdDeviationGazeCoordinatesLeft = 0;
            }

            // Right eye
            if (estimatedGazeCoordinatesRight.Count > 0)
            {
                avgRight = Operations.Mean(estimatedGazeCoordinatesRight.ToArray());
                meanGazeCoordinatesRight.X = (int) avgRight.X;
                meanGazeCoordinatesRight.Y = (int) avgRight.Y;
                varianceRight = Operations.Variance(estimatedGazeCoordinatesRight.ToArray());
                stdDeviationGazeCoordinatesRight = Math.Sqrt(varianceRight.X + varianceRight.Y);
            }
            else
            {
                meanGazeCoordinatesRight.X = 0;
                meanGazeCoordinatesRight.Y = 0;
                stdDeviationGazeCoordinatesRight = 0;
            }
        }
Beispiel #16
0
        /// <summary>
        /// Calculate the angle between 2 GTPoints
        /// </summary>
        /// <param name="newPoint"></param>
        /// <param name="oldPoint"></param>
        /// <returns></returns>
        public static double CalculateAngle(GTPoint newPoint, GTPoint oldPoint)
        {
            double angle;

            if (newPoint.X - oldPoint.X == 0)
            {
                if (newPoint.Y - oldPoint.Y > 0)
                {
                    angle = 90;
                }
                else
                {
                    angle = -90;
                }
            }
            else
            {
                angle = Math.Atan((newPoint.Y - oldPoint.Y) / (newPoint.X - oldPoint.X));
                angle = angle * 180 / Math.PI;
            }

            return(angle);
        }
Beispiel #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="points"></param>
        /// <param name="numPoints"></param>
        /// <returns></returns>
        public static GTPoint[] GetRandomPermutation(GTPoint[] points, int numPoints)
        {
            var randPoints = new GTPoint[numPoints];

            var randomGenerator = new Random();

            var mask = new int[points.Length];
            int randomNumber;

            for (int i = 0; i < mask.Length; i++)
            {
                mask[i] = 0;
            }

            while (Sum(mask) < numPoints)
            {
                randomNumber = randomGenerator.Next(points.Length);
                if (mask[randomNumber] == 0)
                {
                    mask[randomNumber] = 1;
                }
            }

            int counter = 0;

            for (int k = 0; k < mask.Length; k++)
            {
                if (mask[k] == 1)
                {
                    randPoints[counter] = new GTPoint(points[k]);
                    counter++;
                }
            }

            return(randPoints);
        }
Beispiel #18
0
        public GlintConfiguration(Blobs blobs)
        {
            count = blobs.Count;
            centers = new GTPoint[blobs.Count];
            int i = 0;

            foreach (Blob b in blobs.BlobList)
            {
                centers[i] = new GTPoint(b.CenterOfGravity.X, b.CenterOfGravity.Y);
                i++;
            }

            //OrderGlints();

            this.blobs = blobs;
        }
        /// <summary>
        /// Calculates the optimal valid configuration and eliminates the rest of the blobs.
        /// It uses the number of light sources.
        /// </summary>
        public GlintConfiguration GetValidConfiguration(Blobs blobs, GTPoint initialLocation)
        {
            var validConfig = new GlintConfiguration(4);
            var candidateGlintCenters = new Matrix<double>(blobs.Count, blobs.Count);
            Matrix<int> distMatrixThr;
            var combinations = new List<Point>();
            var validConfigurations = new List<GlintConfiguration>();
            var indicesValidConfigs = new List<int>();

            distMatrixThr = GetDistanceMatrix(blobs, MinDistBetweenGlints, MaxDistBetweenGlints);

            for (int i = 0; i < distMatrixThr.Rows; i++)
            {
                combinations.AddRange(GetCombinations(distMatrixThr.GetRow(i).Clone(), i));
            }


            if (combinations.Count > 0)
                validConfig = FilterConfigsByDistance(blobs, combinations, initialLocation);
            else
                validConfig = new GlintConfiguration(1);

            return validConfig;
        }
        private GlintConfiguration FilterConfigsBySize(Blobs blobs, List<Point> combinations, GTPoint initialLocation)
        {
            int N = combinations.Count;

            double maxSize = 0;
            double combinationSize;

            int correctConfigIndex = 0;

            for (int i = 0; i < N; i++)
            {
                combinationSize = blobs.BlobList[(int) combinations[i].X].Area +
                                  blobs.BlobList[(int) combinations[i].Y].Area;
                if (combinationSize > maxSize)
                {
                    correctConfigIndex = i;
                    maxSize = combinationSize;
                }
            }

            return new GlintConfiguration(blobs.BlobList[(int) combinations[correctConfigIndex].X],
                                          blobs.BlobList[(int) combinations[correctConfigIndex].Y]);
        }
        private GlintConfiguration FilterConfigsByDistance(Blobs blobs, List<Point> combinations,
                                                           GTPoint initialLocation)
        {
            int N = combinations.Count;

            double minDistance = 100000000;
            double avgDist = 0;

            int correctConfigIndex = 0;

            for (int i = 0; i < N; i++)
            {
                double dist1 = Operations.Distance(blobs.BlobList[(int) combinations[i].X].CenterOfGravity, initialLocation);
                double dist2 = Operations.Distance(blobs.BlobList[(int) combinations[i].Y].CenterOfGravity, initialLocation);
                avgDist = (dist1 + dist2)/2;

                if (avgDist < minDistance)
                {
                    correctConfigIndex = i;
                    minDistance = avgDist;
                }
            }

            return new GlintConfiguration(blobs.BlobList[(int) combinations[correctConfigIndex].X],
                                          blobs.BlobList[(int) combinations[correctConfigIndex].Y]);
        }
Beispiel #22
0
 public GTPoint Smooth(GTPoint newPoint)
 {
     return newPoint;
 }
Beispiel #23
0
		public void FilterByDistance(GTPoint initialLocation, int N)
		{
			if(N > numBlobs)
				return;

			BlobObject[] finalBlobs = new BlobObject[N];

			double[] distances = new double[numBlobs];
			int[] keys = new int[numBlobs];
			//Matrix<double> distances = new Matrix<double>(numBlobs, 1);
			GTPoint center;

			for (int i = 0; i < numBlobs; i++)
			{
				center = new GTPoint(detectedBlobs[i].CentroidX, detectedBlobs[i].CentroidY);
				distances[i] = Operations.Distance(center, new GTPoint(initialLocation));
				keys[i] = i;
			}

			Array.Sort(distances, keys);

			for (int i = 0; i < numBlobs; i++)
			{
				if (i < N)
					finalBlobs[i] = detectedBlobs[keys[i]];
				else
					detectedBlobs[keys[i]].Clear();
			}

			detectedBlobs = finalBlobs;
			numBlobs = N;

	
		}
Beispiel #24
0
        /// <summary>
        /// Calculate angular velocity
        /// </summary>
        private void CalculateVelocity()
        {
            var newPoint = new GTPoint(recentPoints[recentPoints.Count - 1]);
            var oldPoint = new GTPoint(recentPoints[recentPoints.Count - 2]);
            distPixels = Operations.Distance(newPoint, oldPoint);

            distMm = ConvertPixToMm(distPixels);

            distDegrees = Math.Atan(distMm/10/Settings.Instance.EyeMovement.DistanceUserToScreen);
            distDegrees = distDegrees*180/Math.PI;

            angularVelocity = distDegrees/timeElapsed;

            AddNewVelocity(angularVelocity);
        }
Beispiel #25
0
        private void AddNewPoint(GTPoint newPoint, long time)
        {
            if (recentPoints.Count >= Settings.Instance.EyeMovement.WindowSize)
                recentPoints.RemoveAt(0);

            recentPoints.Add(newPoint);

            timeElapsed = time - previousTime;
            timeElapsed = timeElapsed/1000;
            previousTime = time;
        }
Beispiel #26
0
 public GTPoint(GTPoint point)
 {
     X = point.X;
     Y = point.Y;
 }
Beispiel #27
0
        public bool DetectPupil(Image<Gray, byte> inputImage, TrackData trackData)
        {
            foundPupil = false;
            var initialLocation = new GTPoint(inputImage.Width/2, inputImage.Height/2);

            if (eye == EyeEnum.Left)
                PupilGrayLevel = Settings.Instance.Processing.PupilThresholdLeft;
            else
                PupilGrayLevel = Settings.Instance.Processing.PupilThresholdRight;

            MinPupilSize = Settings.Instance.Processing.PupilSizeMinimum;
            MaxPupilSize = Settings.Instance.Processing.PupilSizeMaximum;

            var min = (int) Math.Round(Math.PI*Math.Pow(MinPupilSize, 2));
            var max = (int) Math.Round(Math.PI*Math.Pow(MaxPupilSize, 2));

            Blobs blobs = blobDetector.DetectBlobs(inputImage, PupilGrayLevel, min, max, false);

            #region Autotuning data store

            if (eye == EyeEnum.Left)
            {
                trackData.UnfilteredBlobCountLeft = blobs.Count;
                trackData.UnfilteredTotalBlobAreaLeft = blobs.TotalArea;
            }
            else
            {
                trackData.UnfilteredBlobCountRight = blobs.Count;
                trackData.UnfilteredTotalBlobAreaRight = blobs.TotalArea;
            }

            #endregion

            //if (blobDetector.IsFiltering == false)
            //    blobs.FilterByArea(10, (int)blobs.TotalArea);

            //Console.WriteLine("Average fullness: {0}", blobs.AverageFullness);

            blobs.EliminateExteriorBlobs();

            if (blobDetector.IsFiltering == false)
                blobs.FilterByArea(min, max);

            if (blobs.Count > 1)
                blobs.FilterByDistance(initialLocation);

            // New, filter by fullness
            //blobs.FilterByFullness(0.40);

            if (blobs.Count > 0)
            {
                //blobDetector.blobCounter.ExtractBlobsImage(inputImage.ToBitmap(), blobs.BlobDir.ElementAt(0).Value, false);
                pupilData.Blob = blobs.BlobDir.ElementAt(0).Value;

                if (pupilData.Blob != null)
                {
                    foundPupil = true;
                    pupilData.Center = new GTPoint(pupilData.Blob.CenterOfGravity.X, pupilData.Blob.CenterOfGravity.Y);

                    // We save the values of the gray level in the corners of rectangle around the pupil blob (which are on the iris)
                    // Javier, the array on EmguGray is [y,x] not [x,y]
                    int x = pupilData.Blob.Rectangle.X;
                    int y = pupilData.Blob.Rectangle.Y;
                    int w = pupilData.Blob.Rectangle.Width;
                    int h = pupilData.Blob.Rectangle.Height;

                    pupilData.GrayCorners[0] = (int) inputImage[y, x].Intensity;
                    pupilData.GrayCorners[1] = (int) inputImage[y, x + w - 1].Intensity;
                    pupilData.GrayCorners[2] = (int) inputImage[y + h - 1, x].Intensity;
                    pupilData.GrayCorners[3] = (int) inputImage[y + h - 1, x + w - 1].Intensity;
                }
            }
            else
                foundPupil = false;

            return foundPupil;
        }
Beispiel #28
0
 public static double Distance(GTPoint p1, Point p2)
 {
     return(Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2)));
 }
Beispiel #29
0
        /// <summary>
        /// Detect glint(s) main method (moved from ImageProcessing)
        /// </summary>
        /// <returns>True if glints detected, false otherwise</returns>
        public bool DetectGlints(Image<Gray, byte> gray, GTPoint pupilCenter)
        {
            bool glintsDetected = false;
            int threshold = Settings.Instance.Processing.GlintThreshold; // default for both eyes

            // Treshold to apply, seperate for each eye.
            if (eye == EyeEnum.Left)
                threshold = Settings.Instance.Processing.GlintThresholdLeft;
            else
                threshold = Settings.Instance.Processing.GlintThresholdRight;

            MinDistBetweenGlints = (int) Math.Floor(0.03*gray.Width);
            MaxDistBetweenGlints = (int) Math.Ceiling(0.5*gray.Width);

            switch (Settings.Instance.Processing.IRPlacement)
            {
                case IRPlacementEnum.Above:

                    if (Settings.Instance.Processing.NumberOfGlints == 1)
                    {
                        glintsDetected = DetectGlintAbove(
                            gray,
                            threshold,
                            Settings.Instance.Processing.GlintSizeMinimum,
                            Settings.Instance.Processing.GlintSizeMaximum,
                            pupilCenter);
                    }
                    else
                    {
                        glintsDetected = DetectTwoGlintsAbove(
                            gray,
                            threshold,
                            Settings.Instance.Processing.GlintSizeMinimum,
                            Settings.Instance.Processing.GlintSizeMaximum,
                            pupilCenter);
                    }
                    break;

                case IRPlacementEnum.Below:

                    if (Settings.Instance.Processing.NumberOfGlints == 1)
                    {
                        glintsDetected = DetectGlintBelow(
                            gray,
                            threshold,
                            Settings.Instance.Processing.GlintSizeMinimum,
                            Settings.Instance.Processing.GlintSizeMaximum,
                            pupilCenter);
                    }
                    else
                    {
                        glintsDetected = DetectTwoGlintsBelow(
                            gray,
                            threshold,
                            Settings.Instance.Processing.GlintSizeMinimum,
                            Settings.Instance.Processing.GlintSizeMaximum,
                            pupilCenter);
                    }
                    break;

                case IRPlacementEnum.None:

                    if (Settings.Instance.Processing.NumberOfGlints == 1)
                    {
                        glintsDetected = DetectGlint(
                            gray,
                            threshold,
                            Settings.Instance.Processing.GlintSizeMinimum,
                            Settings.Instance.Processing.GlintSizeMaximum,
                            pupilCenter);
                    }
                    else if (Settings.Instance.Processing.NumberOfGlints == 2)
                    {
                        glintsDetected = DetectTwoGlints(
                            gray,
                            threshold,
                            Settings.Instance.Processing.GlintSizeMinimum,
                            Settings.Instance.Processing.GlintSizeMaximum,
                            pupilCenter);
                    }
                    break;

                case IRPlacementEnum.BelowAndAbove:

                    if (Settings.Instance.Processing.NumberOfGlints == 2)
                    {
                        glintsDetected = DetectTwoGlints(
                            gray,
                            threshold,
                            Settings.Instance.Processing.GlintSizeMinimum,
                            Settings.Instance.Processing.GlintSizeMaximum,
                            pupilCenter);
                    }
                    break;
            }
            //Performance.Now.Stamp("Glint detected");

            return glintsDetected;
        }
Beispiel #30
0
 public GTPoint(GTPoint point)
 {
     X = point.X;
     Y = point.Y;
 }
Beispiel #31
0
        public GlintConfiguration(Blob blob0, Blob blob1)
        {
            count = 2;
            centers = new GTPoint[2];
            blobs = new Blobs();

            blobs.BlobDir[0] = blob0;
            blobs.BlobDir[1] = blob1;

            centers[0] = new GTPoint(blob0.CenterOfGravity.X, blob0.CenterOfGravity.Y);
            centers[1] = new GTPoint(blob1.CenterOfGravity.X, blob1.CenterOfGravity.Y);
        }
Beispiel #32
0
		/// <summary>
		/// Select the blob closest to the initial location
		/// </summary>
		/// <param name="initialLocation">GTPoint</param>
		/// <returns>Blob</returns>
		public BlobObject FilterByDistance(GTPoint initialLocation)
		{
			double[] distances = new double[numBlobs];
			int[] keys = new int[numBlobs];
			GTPoint center;

			for (int i = 0; i < numBlobs; i++)
			{
				center = new GTPoint(detectedBlobs[i].CentroidX, detectedBlobs[i].CentroidY);
				distances[i] = Operations.Distance(center, new GTPoint(initialLocation));
				keys[i] = i;
			}

			Array.Sort(distances, keys);		

			return GetBlob(keys[0]);

		}
    private void tcpipServer_OnCalibrationFeedbackPoint(long time, int packagenumber, int targetX, int targetY,
                                                        int gazeX, int gazeY, float distance, int acquisitionTime)
    {
      CalibrationWindow.Instance.Dispatcher.Invoke
          (
              DispatcherPriority.ApplicationIdle,
              new Action
                  (
                  delegate
                  {
                    //pass info from the dedicated interface to the tracker class
                    var target = new System.Drawing.Point(targetX, targetY);
                    var gaze = new GTPoint(gazeX, gazeY);
                    //tracker.SaveRecalibInfo(time, packagenumber, target, gaze);

                    /* outputting the data in a local class */
                    string del = " ";
                    string msg = DateTime.Now.Ticks + del
                                 + time + del
                                 + packagenumber + del
                                 + targetX + del
                                 + targetX + del
                                 + gazeX + del
                                 + gazeY + del
                                 + distance + del
                                 + acquisitionTime;
                    Output.Instance.appendToFile(msg);
                  }
                  )
          );
    }
Beispiel #34
0
        /// <summary>
        /// Smooth method. Call this method when we get a new
        /// sample and it will return the smoothed coordinates
        /// </summary>
        /// <param name="newPoint">New gazed point</param>
        /// <returns>Smoothed point</returns>
        /// 
        public GTPoint Smooth(GTPoint newPoint)
        {
            GTPoint smoothedPoint;

            stddev = (int) Math.Ceiling(Settings.Instance.EyeMovement.SmoothLevel/5.0);

            if (data.Count < numberOfSamples)
                data.Add(newPoint);
            else
            {
                data.RemoveAt(0);
                data.Add(newPoint);
            }

            //Javier: this has been incorporated in the eye movement detection, where it belongs
            //if (GetMaxDistanceOnWindow() > maxDistance)
            //    smoothedPoint = newPoint;
            //else
            //{
            var sum = new GTPoint(0, 0);
            double sumWeights = 0;
            double weight;

            for (int i = 0; i < data.Count; i++)
            {
                weight = GetGaussWeight(data.Count - i - 1, mean, stddev);
                sum.X += data[i].X*weight;
                sum.Y += data[i].Y*weight;

                sumWeights += weight;
            }

            smoothedPoint = new GTPoint(sum.X/sumWeights, sum.Y/sumWeights);
            //}

            return smoothedPoint;
        }
Beispiel #35
0
        /// <summary>
        /// Standard deviation of an array of GTPoints
        /// </summary>
        /// <param name="num"></param>
        /// <returns>GTPoint</returns>
        public static GTPoint StandardDeviation(GTPoint[] num)
        {
            GTPoint variance = Variance(num);

            return(new GTPoint(Math.Sqrt(variance.X), Math.Sqrt(variance.Y)));
        }
Beispiel #36
0
        private void CalculateGazeCoordinates(TrackData td)
        {
            GTPoint gazedCoordinatesLeft;
            GTPoint gazedCoordinatesRight = new GTPoint();
            GTPoint smoothedCoordinates;

            #region Monocular/Left eye

            calibration.PupilCenterLeft = trackData.PupilDataLeft.Center;

            if (Settings.Instance.Processing.TrackingGlints)
                calibration.GlintConfigLeft = td.GlintDataLeft.Glints;

            gazedCoordinatesLeft = calibration.GetGazeCoordinates(td, EyeEnum.Left);

            #endregion

            #region Binocular/Right eye

            if (Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular)
            {
                calibration.PupilCenterRight = td.PupilDataRight.Center;

                if (Settings.Instance.Processing.TrackingGlints)
                    calibration.GlintConfigRight = td.GlintDataRight.Glints;

                gazedCoordinatesRight = calibration.GetGazeCoordinates(td, EyeEnum.Right);
            }

            #endregion

            #region Smoothing/Eye movement state

            if (Settings.Instance.Processing.EyeMouseSmooth)
            {
                var p = new GTPoint(gazedCoordinatesLeft.X, gazedCoordinatesLeft.Y);

                if (Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular)
                {
                    if (gazedCoordinatesRight.Y != 0 && gazedCoordinatesRight.X != 0)
                    {
                        p.X += gazedCoordinatesRight.X;
                        p.Y += gazedCoordinatesRight.Y;
                        p.X = p.X / 2;
                        p.Y = p.Y / 2;
                    }
                }

                this.eyeMovement.CalculateEyeMovement(p);

                smoothedCoordinates = exponentialSmoother.Smooth(p);

                //if (this.eyeMovement.EyeMovementState == Classifier.EyeMovementStateEnum.Fixation)
                //    smoothedCoordinates = exponentialSmoother.Smooth(p);
                //else
                //{
                //    smoothedCoordinates = p;
                //    this.exponentialSmoother.Stop();
                //}
                trackData.EyeMovement = this.eyeMovement.EyeMovementState;
                gazeDataSmoothed.Set(smoothedCoordinates.X, smoothedCoordinates.Y, smoothedCoordinates.X, smoothedCoordinates.Y);
            }

            #endregion

            #region Set values, raise events

            // trigger OnGazeData events
            this.gazeDataRaw.Set(
              gazedCoordinatesLeft.X,
              gazedCoordinatesLeft.Y,
              gazedCoordinatesRight.X,
              gazedCoordinatesRight.Y);

            this.trackData.GazeDataRaw = this.gazeDataRaw;
            this.trackData.GazeDataSmoothed = this.gazeDataSmoothed;

            // Trigger OnExtendedGazeData events
            this.gazeDazaExtended.Set(
                this.trackData.TimeStamp,
                this.gazeDataRaw.GazePositionX,
                this.gazeDataRaw.GazePositionY,
                this.trackData.PupilDataLeft.Diameter,
                this.trackData.PupilDataRight.Diameter);

            #endregion
        }
        /// <summary>
        /// Set the ROI of an image around a central point given the radius, which would
        /// correspond to the radius of the inscribed circle (e.g a pupil). The method
        /// checks whether the ROI is actually within the limits of the image. If it's
        /// not, the ROI will not be set and the method return false
        /// </summary>
        /// <param name="image">Input image</param>
        /// <param name="center">Central point</param>
        /// <param name="radius">The radius of the roi.</param>
        /// <returns>True if succesfull, otherwise false.</returns>
        /// 
        private static Rectangle SetROI(Size imageSize, GTPoint center, double diameter)
        {
            var ROI = new Rectangle();

            double aspectRatio = imageSize.Width/(double) imageSize.Height;
            double r = 2.5*diameter;

            var roiSize = new Size((int) (aspectRatio*r), (int) (aspectRatio*r));

            if (center.X - roiSize.Width > 0 &&
                center.Y - roiSize.Height > 0 &&
                center.X + roiSize.Width < imageSize.Width &&
                center.Y + roiSize.Height < imageSize.Height)
            {
                ROI = new Rectangle(
                    (int) Math.Round(center.X) - roiSize.Width/2,
                    (int) Math.Round(center.Y) - roiSize.Height/2,
                    roiSize.Width,
                    roiSize.Height);
            }
            else
                ROI = new Rectangle(new Point(0, 0), roiSize);

            return ROI;
        }
        public void RecalibrateOffset(GTPoint gazeCoords, Point targetCoords)
        {
            double distanceX = gazeCoords.X - targetCoords.X;
            double distanceY = gazeCoords.Y - targetCoords.Y;

            calibration.CalibMethod.CalibrationDataLeft.CoeffsX[0, 0] -= distanceX/2;
            calibration.CalibMethod.CalibrationDataLeft.CoeffsY[0, 0] -= distanceY/2;

            if (GTSettings.Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular)
            {
                calibration.CalibMethod.CalibrationDataRight.CoeffsX[0, 0] += distanceX/2;
                calibration.CalibMethod.CalibrationDataRight.CoeffsY[0, 0] += distanceY/2;
            }

            OnRecalibrationAvailable();
        }
Beispiel #39
0
        /// <summary>
        /// Detect two pupils
        /// </summary>
        /// <param name="inputImage">Input image in grayscale</param>
        /// <returns></returns>
        public bool DetectTwoPupils(Image<Gray, byte> inputImage, TrackData trackData)
        {
            foundPupil = false;
            var initialLocation = new GTPoint(inputImage.Width/2, inputImage.Height/2);

            PupilGrayLevel = Settings.Instance.Processing.PupilThreshold;
            MinPupilSize = Settings.Instance.Processing.PupilSizeMinimum;
            MaxPupilSize = Settings.Instance.Processing.PupilSizeMaximum;

            double min = Math.PI*Math.Pow(MinPupilSize, 2);
            double max = Math.PI*Math.Pow(MaxPupilSize, 2);

            Blobs blobs = blobDetector.DetectBlobs(inputImage, PupilGrayLevel, (int) min, (int) max, false);
            blobs.EliminateExteriorBlobs();

            if (blobDetector.IsFiltering == false)
                blobs.FilterByArea((int) min, (int) max);

            // We have 2 or more candidates
            if (blobs.Count > 1)
            {
                pupilData.Blob = blobs.FilterByDistance(initialLocation);

                if (pupilData.Blob != null)
                {
                    foundPupil = true;
                    pupilData.Center = new GTPoint(pupilData.Blob.CenterOfGravity.X, pupilData.Blob.CenterOfGravity.Y);
                }
            }
            else
                foundPupil = false;

            return foundPupil;
        }