From 87e44eede5c7b51b77b0cc341bbbf3e846031eda Mon Sep 17 00:00:00 2001 From: Stefan Schreistetter Date: Thu, 29 Aug 2019 12:25:03 +0200 Subject: [PATCH] Added filtering to GazeDataProcessor. --- GazeWebSocketServer/DSP/FIRfilt.cs | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GazeWebSocketServer/GazeDataProcessor.cs | 44 ++++++++++++++++++++++++++++++++++++++------ GazeWebSocketServer/GazeWebSocketServer.csproj | 1 + 3 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 GazeWebSocketServer/DSP/FIRfilt.cs diff --git a/GazeWebSocketServer/DSP/FIRfilt.cs b/GazeWebSocketServer/DSP/FIRfilt.cs new file mode 100644 index 0000000..92c88d4 --- /dev/null +++ b/GazeWebSocketServer/DSP/FIRfilt.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GazeWebSocketServer.DSP +{ + class FIRfilt + { + public Double[] Coefficients { + get => coefficients; + private set { + coefficients = value; + Initialize(); + } + } + public Boolean OutputValid { get; private set; } + public Double? Output { + get { + if (OutputValid) + { + return output; + } + else + { + return null; + } + } + } + + private Double output; + private Double[] ringBuffer; + private Int64 currentValueIndex; + private Double[] coefficients; + + public FIRfilt(Double[] coefficients) + { + Coefficients = coefficients; + } + + public static FIRfilt[] createFilterArray(Double[] coefficients, Int64 numberOfFilters) + { + FIRfilt[] firFilts = new FIRfilt[numberOfFilters]; + for(Int64 index= 0; index < firFilts.Length; index++) + { + firFilts[index] = new FIRfilt(coefficients); + } + return firFilts; + } + + private void Initialize() + { + ringBuffer = new Double[Coefficients.Length]; + for (Int64 index = 0; index < ringBuffer.Length; index++) + { + ringBuffer[index] = 0.0; + } + + currentValueIndex = 0; + output = 0.0; + OutputValid = false; + } + + public void Input(Double input) + { + ringBuffer[currentValueIndex] = input; + output = 0.0; + for (Int64 index = 0; index < ringBuffer.Length; index++)//parallelizable + { + output += ringBuffer[(currentValueIndex + index) % Coefficients.Length] * Coefficients[index]; + } + + currentValueIndex = (currentValueIndex + 1) % Coefficients.Length; + if(!OutputValid && currentValueIndex == 0) + { + OutputValid = true; + } + } + } +} diff --git a/GazeWebSocketServer/GazeDataProcessor.cs b/GazeWebSocketServer/GazeDataProcessor.cs index adc6a58..350633e 100644 --- a/GazeWebSocketServer/GazeDataProcessor.cs +++ b/GazeWebSocketServer/GazeDataProcessor.cs @@ -5,26 +5,58 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tobii.Research; +using GazeWebSocketServer.DSP; namespace GazeWebSocketServer { class GazeDataProcessor { - readonly float screenHeight; - readonly float screenWidth; + private readonly Double screenHeight; + private readonly Double screenWidth; + private FIRfilt filtLeftEyeX; + private FIRfilt filtLeftEyeY; + private FIRfilt filtRightEyeX; + private FIRfilt filtRightEyeY; public GazeDataProcessor() { screenHeight = Convert.ToSingle(SystemParameters.PrimaryScreenHeight); screenWidth = Convert.ToSingle(SystemParameters.PrimaryScreenWidth); + FIRfilt[] filters = FIRfilt.createFilterArray(new Double[] { 0.00490811980494201, 0.00394529962944205, - 0.00964707695734475, + - 0.0111481165779560, - 0.00440433399899739, - 0.0148433230170450, + - 0.000941679361561877, 0.0373490622242201, 0.0175330755932427, + - 0.00111444062672272, 0.0512529971125828, 0.0232019172099006, + - 0.0659097689575874, - 0.0163424387855043, - 0.0336732269089631, + - 0.238683101182416, - 0.108915205128799, 0.367003181497664, + 0.367003181497664, - 0.108915205128799, - 0.238683101182416, + - 0.0336732269089631, - 0.0163424387855043, - 0.0659097689575874, + 0.0232019172099006, 0.0512529971125828, - 0.00111444062672272, + 0.0175330755932427, 0.0373490622242201, - 0.000941679361561877, + - 0.0148433230170450, - 0.00440433399899739, - 0.0111481165779560, + - 0.00964707695734475, 0.00394529962944205, 0.00490811980494201 }, 4); + filtLeftEyeX = filters[0]; + filtLeftEyeY = filters[1]; + filtRightEyeX = filters[2]; + filtRightEyeY = filters[3]; } public GazeData Extract(GazeDataEventArgs e) { - GazeData data = new GazeData(e.LeftEye.GazePoint.PositionOnDisplayArea.X*screenWidth, - e.LeftEye.GazePoint.PositionOnDisplayArea.Y*screenHeight, - e.RightEye.GazePoint.PositionOnDisplayArea.X*screenWidth, - e.RightEye.GazePoint.PositionOnDisplayArea.Y*screenHeight, + if(e.LeftEye.GazePoint.Validity == Validity.Valid) + { + filtLeftEyeX.Input(e.LeftEye.GazePoint.PositionOnDisplayArea.X); + filtLeftEyeY.Input(e.LeftEye.GazePoint.PositionOnDisplayArea.Y); + } + if (e.RightEye.GazePoint.Validity == Validity.Valid) + { + filtRightEyeX.Input(e.RightEye.GazePoint.PositionOnDisplayArea.X); + filtRightEyeY.Input(e.RightEye.GazePoint.PositionOnDisplayArea.Y); + } + + GazeData data = new GazeData(filtLeftEyeX.Output.HasValue ? Convert.ToSingle(filtLeftEyeX.Output * screenWidth) : Single.NaN, + filtLeftEyeY.Output.HasValue ? Convert.ToSingle(filtLeftEyeY.Output * screenHeight) : Single.NaN, + filtRightEyeX.Output.HasValue ? Convert.ToSingle(filtRightEyeX.Output * screenWidth) : Single.NaN, + filtRightEyeY.Output.HasValue ? Convert.ToSingle(filtRightEyeY.Output * screenHeight) : Single.NaN, e.DeviceTimeStamp, e.SystemTimeStamp); return data; diff --git a/GazeWebSocketServer/GazeWebSocketServer.csproj b/GazeWebSocketServer/GazeWebSocketServer.csproj index b75a431..192788c 100644 --- a/GazeWebSocketServer/GazeWebSocketServer.csproj +++ b/GazeWebSocketServer/GazeWebSocketServer.csproj @@ -54,6 +54,7 @@ + -- libgit2 0.26.0