/// <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; }
public GlintConfiguration(Blob blob) { count = 1; centers = new GTPoint[1]; blobs.BlobDir[0] = blob; centers[0] = new GTPoint(blob.CenterOfGravity.X, blob.CenterOfGravity.Y); }
/// <summary> /// Order any 4 points /// </summary> /// <param name="points">Array of 4 points</param> /// <returns>Ordered array of the 4 points</returns> public static GTPoint[] OrderPoints(GTPoint[] points) { int N = 4; var orderedPoints = new GTPoint[N]; var center = new GTPoint(); if (points.Length != N) { Console.WriteLine("error ordering 4 glints"); } else { center = Mean(points); var 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); }
// 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; }
/// <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); }
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(); } }
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); }
/// <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; }
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); }
/// <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; } }
/// <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); }
/// <summary> /// Detect glints in a grayscale image. /// This method will select the blob closest to coordinates of initialLocation /// </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 DetectGlint(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); if (blobs.Count > 1) blobs.FilterByDistance(initialLocation); if (blobs.Count > 0) { glintData.Glints = new GlintConfiguration(blobs); foundGlints = true; } return foundGlints; }
/// <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); }
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)); }
/// <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; }
/// <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; }
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))); }
/// <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++; } }
/// <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); }
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; }
public PupilData() { Eye = EyeEnum.Left; Center = new GTPoint(); GrayCorners = new int[4]; }
public GTPoint(GTPoint point) { X = point.X; Y = point.Y; }
/// <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; }
/// <summary> /// Order any 4 points /// </summary> /// <param name="points">Array of 4 points</param> /// <returns>Ordered array of the 4 points</returns> public static GTPoint[] OrderPoints(GTPoint[] points) { int N = 4; var orderedPoints = new GTPoint[N]; var center = new GTPoint(); if (points.Length != N) { Console.WriteLine("error ordering 4 glints"); } else { center = Mean(points); var 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; }
public GTPoint Smooth(GTPoint newPoint) { return newPoint; }
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(); }
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); } ) ); }
/// <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; }
/// <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; }
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; }
/// <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); }
/// <summary> /// Variance of an array of GTPoints /// </summary> /// <param name="num">Array of GTPoint</param> /// <returns>Variance</returns> public static GTPoint Variance(GTPoint[] num) { if (num.Length < 2) return new GTPoint(0, 0); double SumX = 0.0, SumOfSqrsX = 0.0; double SumY = 0.0, SumOfSqrsY = 0.0; for (int i = 0; i < num.Length; i++) { SumX += num[i].X; SumY += num[i].Y; SumOfSqrsX += Math.Pow(num[i].X, 2); SumOfSqrsY += Math.Pow(num[i].Y, 2); } double topSumX = (num.Length*SumOfSqrsX) - (Math.Pow(SumX, 2)); double topSumY = (num.Length*SumOfSqrsY) - (Math.Pow(SumY, 2)); double n = num.Length; return new GTPoint((topSumX/(n*(n - 1))), topSumY/(n*(n - 1))); }
/// <summary> /// Select the blob closest to the initial location /// </summary> /// <param name="initialLocation">GTPoint</param> /// <returns>Blob</returns> public Blob FilterByDistance(GTPoint initialLocation) { FilterByDistance(initialLocation, 1); return BlobList[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)); }
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); } } }
/// <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))); }