Пример #1
0
        /// <summary>
        /// Select the maxNumber blobs closes to the initial location
        /// </summary>
        /// <param name="initialLocation"></param>
        /// <param name="maxNumber"></param>
        public void FilterByDistance(GTPoint initialLocation, int maxNumber)
        {
            var     distances = new double[blobDir.Count];
            var     keys      = new int[blobDir.Count];
            GTPoint center;

            int i = 0;

            foreach (Blob b in blobDir.Values)
            {
                center       = new GTPoint(b.CenterOfGravity.X, b.CenterOfGravity.Y);
                distances[i] = Operations.Distance(center, new GTPoint(initialLocation));
                keys[i]      = b.ID;
                i++;
            }

            Array.Sort(distances, keys);

            int j = 0;

            foreach (int key in keys)
            {
                if (j > maxNumber - 1)
                {
                    RemoveBlob(keys[j]);
                }
                j++;
            }
        }
        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]));
        }
        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);
            }
                )
            );
        }
Пример #4
0
        public void FilterByLocation(GTPoint initialLocation, int maxNumber, int position)
        {
            var center = new GTPoint();

            // Glint(s) above pupil, we eliminate blobs below (i.e., when glint.y > pupil.y)
            if (position == 1)
            {
                foreach (Blob blob in BlobList)
                {
                    center = new GTPoint(blob.CenterOfGravity.X, blob.CenterOfGravity.Y);

                    if (center.Y > initialLocation.Y)
                    {
                        RemoveBlob(blob.ID);
                    }
                }
            }

            // Glint(s) below pupil, we eliminate blobs above (i.e., when glint.y < pupil.y)
            else if (position == -1)
            {
                foreach (Blob blob in BlobList)
                {
                    center = new GTPoint(blob.CenterOfGravity.X, blob.CenterOfGravity.Y);

                    if (center.Y < initialLocation.Y)
                    {
                        RemoveBlob(blob.ID);
                    }
                }
            }
        }
Пример #5
0
        private static Rectangle SetROI(Size imageSize, GTPoint center, double radius)
        {
            var  ROI     = new Rectangle();
            bool success = false;

            double aspectRatio = imageSize.Width / imageSize.Height;
            double r           = 3 * radius;

            var roiSize = new Size((int)(aspectRatio * r), (int)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,
                    (int)Math.Round(center.Y) - roiSize.Height,
                    roiSize.Width * 2,
                    roiSize.Height * 2);
                success = true;
            }
            else
            {
                ROI     = new Rectangle(new Point(0, 0), roiSize);
                success = false;
            }

            return(ROI);
        }
        /// <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);
        }
Пример #7
0
        /// <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 successful, 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);
        }
Пример #8
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);
        }
Пример #9
0
        public override GTPoint GetGazeCoordinates(TrackData trackData, EyeEnum eye)
        {
            var row = new Matrix <double>(6, 1);
            var screenCoordinates = new Matrix <double>(2, 1);

            var gazedPoint = new GTPoint();

            try
            {
                double X = 0;
                double Y = 0;

                switch (eye)
                {
                case EyeEnum.Left:
                    X = trackData.PupilDataLeft.Center.X - trackData.GlintDataLeft.Glints.AverageCenter.X;
                    Y = trackData.PupilDataLeft.Center.Y - trackData.GlintDataLeft.Glints.AverageCenter.Y;
                    break;

                default:
                    X = trackData.PupilDataRight.Center.X - trackData.GlintDataRight.Glints.AverageCenter.X;
                    Y = trackData.PupilDataRight.Center.Y - trackData.GlintDataRight.Glints.AverageCenter.Y;
                    break;
                }

                row[0, 0] = 1;
                row[1, 0] = X;
                row[2, 0] = Y;
                row[3, 0] = X * Y;
                row[4, 0] = X * X;
                row[5, 0] = Y * Y;

                if (eye == EyeEnum.Left)
                {
                    if (CalibrationDataLeft != null && CalibrationDataLeft.CoeffsX != null)
                    {
                        gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsX.Ptr);
                        gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsY.Ptr);
                    }
                }
                else
                {
                    if (CalibrationDataRight != null && CalibrationDataRight.CoeffsX != null)
                    {
                        gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsX.Ptr);
                        gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsY.Ptr);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine("Calibration.cs, exception in GetGazeCoordinates(), message: " + ex.Message);
            }

            return(gazedPoint);
        }
Пример #10
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;
 }
Пример #11
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();
            }
        }
Пример #12
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);
        }
Пример #13
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;
        }
Пример #14
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;
            }
        }
Пример #15
0
        private void AddNewPoint(GTPoint newPoint, long time)
        {
            if (recentPoints.Count >= windowSize)
            {
                recentPoints.RemoveAt(0);
            }

            recentPoints.Add(newPoint);

            timeElapsed  = time - previousTime;
            timeElapsed  = timeElapsed / 1000;
            previousTime = time;
        }
Пример #16
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);
        }
Пример #17
0
        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();
        }
Пример #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;
        }
Пример #19
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);
        }
Пример #20
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]));
        }
Пример #21
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);
            }
        }
Пример #22
0
        /// <summary>
        /// Detect two glints in a grayscale image.
        /// This method will select the two glints closest to the initial location that are
        /// below the pupil (i.e., glints.y > pupil.y)
        /// </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 DetectTwoGlintsBelow(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);
            }

            // Eliminate blobs above initialLocation (pupil center)
            blobs.FilterByLocation(initialLocation, 2, -1);

            if (blobs.Count > 1)
            {
                //blobs.FilterByDistance(initialLocation, 2);
                //glintData.Glints = new GlintConfiguration(blobs);

                glintData.Glints = GetValidConfiguration(blobs, initialLocation);


                // store blobcount for autotune
                glintData.Glints.UnfilteredCount     = unfilteredCount;
                glintData.Glints.UnfilteredTotalArea = unfilteredArea;

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

            return(foundGlints);
        }
Пример #23
0
        private double GetMaxDistanceOnWindow()
        {
            GTPoint centroid = Operations.Mean(data.ToArray());

            double maxDist = 0;
            double dist    = 0;

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

            return(maxDist);
        }
Пример #24
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);
        }
Пример #25
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);
        }
Пример #26
0
        /// <summary>
        /// Detect the pupil in a grayscale image. The blob closest to the glints will
        /// be considered to be the pupil. To do: check for eccentricity
        /// </summary>
        /// <param name="inputImage">Input image in grayscale</param>
        /// <param name="pupilGrayLevel">Gray level used to threshold the image</param>
        /// <param name="minPupilSize">Minimum pupil size allowed</param>
        /// <param name="maxPupilSize">Maximum pupil size allowed</param>
        /// <param name="glints">Glints detected in the image, passed as a GlintConfiguration
        /// class</param>
        /// <returns></returns>
        //public bool DetectPupil(Image<Gray, byte> inputImage, int pupilGrayLevel,
        //    int minPupilSize, int maxPupilSize, GlintConfiguration glints)
        //{
        //    bool errorPupil = true;
        //    List<Blob> filteredBlobs = new List<Blob>();

        //if(eye == EyeEnum.Left)
        //    this.pupilGrayLevel = Settings.Instance.Processing.PupilThresholdLeft;
        //else
        //    this.pupilGrayLevel = Settings.Instance.Processing.PupilThresholdRight;
        //    this.minPupilSize = minPupilSize;
        //    this.maxPupilSize = maxPupilSize;

        //    blobResult = new BlobResult(inputImage, pupilGrayLevel, true);

        //    blobResult.FilterByArea((int)(Math.PI * Math.Pow(minPupilSize, 2)), (int)(Math.PI * Math.Pow(maxPupilSize, 2)));


        //    if (blobResult.detectedBlobs.Length > 0)
        //    {
        //        pupilData.Blob = blobResult.FilterByDistance(glints.averageCenter);

        //        if (pupilData.Blob != null)
        //            errorPupil = false;
        //        else
        //            errorPupil = true;

        //    }

        //    else
        //        errorPupil = true;

        //    if (blobResult != null)
        //        blobResult.ClearBlobResult();

        //    return errorPupil;
        //}

        #endregion

        #region Detect two pupils

        /// <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);
        }
Пример #27
0
        /// <summary>
        /// This method calculates the average of the estimated gazed coordinates
        /// (once calibration is finished)
        /// </summary>
        public void CalculateAverageCoords()
        {
            GTPoint avgLeft       = new GTPoint();
            GTPoint avgRight      = new GTPoint();
            GTPoint varianceLeft  = new GTPoint();
            GTPoint 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;
            }
        }
Пример #28
0
        public GTPoint GetGazeCoordinates(EyeEnum eye)
        {
            var row = new Matrix <double>(6, 1);
            var screenCoordinates = new Matrix <double>(2, 1);

            var    gazedPoint = new GTPoint();
            double x, y;

            if (eye == EyeEnum.Left)
            {
                x = PupilCenterLeft.X;
                y = PupilCenterLeft.Y;
            }
            else
            {
                x = PupilCenterRight.X;
                y = PupilCenterRight.Y;
            }

            row[0, 0] = 1;
            row[1, 0] = x;
            row[2, 0] = y;
            row[3, 0] = x * y;
            row[4, 0] = x * x;
            row[5, 0] = y * y;

            if (eye == EyeEnum.Left)
            {
                gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsX.Ptr);
                gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsY.Ptr);
            }
            else
            {
                gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsX.Ptr);
                gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsY.Ptr);
            }

            return(gazedPoint);
        }
Пример #29
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;
        }
Пример #30
0
        public GTPoint GetGazeCoordinates(EyeEnum eye, GTPoint pupilCenter, GlintConfiguration glintConfig)
        {
            var row = new Matrix <double>(6, 1);
            var screenCoordinates = new Matrix <double>(2, 1);

            var    gazedPoint = new GTPoint();
            double X, Y;

            try
            {
                X = pupilCenter.X - glintConfig.AverageCenter.X;
                Y = pupilCenter.Y - glintConfig.AverageCenter.Y;

                row[0, 0] = 1;
                row[1, 0] = X;
                row[2, 0] = Y;
                row[3, 0] = X * Y;
                row[4, 0] = X * X;
                row[5, 0] = Y * Y;

                if (eye == EyeEnum.Left)
                {
                    gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsX.Ptr);
                    gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsY.Ptr);
                }
                else
                {
                    gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsX.Ptr);
                    gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsY.Ptr);
                }
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine("Calibration.cs, exception in GetGazeCoordinates(), message: " + ex.Message);
            }

            return(gazedPoint);
        }