private static void ParseSignature(Signature signature, string[] linesArray, bool standardFeatures) { linesArray = linesArray.Skip(1).ToArray(); var lines = linesArray .Where(l => !string.IsNullOrWhiteSpace(l)) .Select(l => l.Split(' ').Select(s => int.Parse(s)).ToArray()) .ToList(); // Remove noise (points with 0 pressure) from the beginning of the signature while (lines.Count > 0 && lines[0][2] == 0) { lines.RemoveAt(0); } // Remove noise (points with 0 pressure) from the end of the signature while (lines.Count > 0 && lines[lines.Count - 1][2] == 0) { lines.RemoveAt(lines.Count - 1); } // The database uses special datapoints to signal stroke boundaries // We are going to replace them with averaged values to allow for smoother comparison for (int i = 1; i < lines.Count - 1; i++) { if (lines[i][0] != -1) { continue; } if (lines[i][0] == -1 && lines[i + 1][0] == -1) { // Remove duplicate stroke boundaries lines.RemoveAt(i); i--; continue; } lines[i][0] = (lines[i - 1][0] + lines[i + 1][0]) / 2; lines[i][1] = (lines[i - 1][1] + lines[i + 1][1]) / 2; lines[i][2] = 0; } signature.SetFeature(SigComp15.X, lines.Select(l => l[0]).ToList()); signature.SetFeature(SigComp15.Y, lines.Select(l => l[1]).ToList()); signature.SetFeature(SigComp15.P, lines.Select(l => l[2]).ToList()); // Sampling frequency is 75Hz ==> time should be increased by 13.333 msec for each slot signature.SetFeature(SigComp15.T, Enumerable.Range(0, lines.Count).Select(i => i * (1.0 / 75.0) * 1000).ToList()); if (standardFeatures) { signature.SetFeature(Features.X, lines.Select(l => (double)l[0]).ToList()); signature.SetFeature(Features.Y, lines.Select(l => (double)l[1]).ToList()); signature.SetFeature(Features.Pressure, lines.Select(l => (double)l[2]).ToList()); signature.SetFeature(Features.T, Enumerable.Range(0, lines.Count).Select(i => i * 5d).ToList()); signature.SetFeature(Features.Button, lines.Select(l => l[2] > 0).ToList()); signature.SetFeature(Features.Azimuth, lines.Select(l => 1d).ToList()); signature.SetFeature(Features.Altitude, lines.Select(l => 1d).ToList()); signature.CalculateStandardStatistics(); } }
private static void ParseSignature(Signature signature, string[] linesArray, bool standardFeatures) { linesArray = linesArray.Skip(1).ToArray(); var lines = linesArray .Where(l => !string.IsNullOrWhiteSpace(l)) .Select(l => l.Split(' ').Select(s => int.Parse(s)).ToArray()) .ToList(); // Remove noise (points with 0 pressure) from the beginning of the signature while (lines.Count > 0 && lines[0][2] == 0) { lines.RemoveAt(0); } // Remove noise (points with 0 pressure) from the end of the signature while (lines.Count > 0 && lines[lines.Count - 1][2] == 0) { lines.RemoveAt(lines.Count - 1); } signature.SetFeature(SigComp13Japanese.X, lines.Select(l => l[0]).ToList()); signature.SetFeature(SigComp13Japanese.Y, lines.Select(l => l[1]).ToList()); signature.SetFeature(SigComp13Japanese.P, lines.Select(l => l[2]).ToList()); // Sampling frequency is 200Hz ==> time should be increased by 5 msec for each slot signature.SetFeature(SigComp13Japanese.T, Enumerable.Range(0, lines.Count).Select(i => i * 5).ToList()); if (standardFeatures) { signature.SetFeature(Features.X, lines.Select(l => (double)l[0]).ToList()); signature.SetFeature(Features.Y, lines.Select(l => (double)l[1]).ToList()); signature.SetFeature(Features.Pressure, lines.Select(l => (double)l[2]).ToList()); signature.SetFeature(Features.T, Enumerable.Range(0, lines.Count).Select(i => i * 5d).ToList()); signature.SetFeature(Features.Button, lines.Select(l => l[2] > 0).ToList()); signature.SetFeature(Features.Azimuth, lines.Select(l => 1d).ToList()); signature.SetFeature(Features.Altitude, lines.Select(l => 1d).ToList()); signature.CalculateStandardStatistics(); } }
/// <summary> /// Loads one signature from specified stream. /// </summary> /// <remarks> /// Based on Mohammad's MCYT reader. /// </remarks> /// <param name="signature">Signature to write features to.</param> /// <param name="stream">Stream to read MCYT data from.</param> /// <param name="standardFeatures">Convert loaded data to standard <see cref="Features"/>.</param> public static void LoadSignature(Signature signature, MemoryStream stream, bool standardFeatures) { BinaryReader reader = new BinaryReader(stream); var fpg = reader.ReadChars(4); // FPG var hsize = reader.ReadUInt16(); // Header size int ver = 1; if ((hsize == 48) || (hsize == 60)) { ver = 2; } ushort format = reader.ReadUInt16(); // should be '4' var m = reader.ReadUInt16(); var can = reader.ReadUInt16(); var Ts = reader.ReadUInt32(); var res = reader.ReadUInt16(); var ignore = reader.ReadBytes(4); var coef = reader.ReadUInt32(); var mvector = reader.ReadUInt32(); // length of vector var nvectores = reader.ReadUInt32(); // number of vectors var nc = reader.ReadUInt16(); uint Fs = 0, mventana = 0, msolapadas = 0; if (ver == 2) { Fs = reader.ReadUInt32(); mventana = reader.ReadUInt32(); msolapadas = reader.ReadUInt32(); } stream.Seek(hsize - 12, SeekOrigin.Begin); var datos = reader.ReadUInt32(); var delta = reader.ReadUInt32(); var ddelta = reader.ReadUInt32(); stream.Seek(hsize, SeekOrigin.Begin); // not actually needed if (res != 32) { //TODO: ezt loggolni new NotSupportedException("Only 32 bit floating point values are supported at the moment"); } List <double> X = new List <double>(); List <double> Y = new List <double>(); List <double> Pressure = new List <double>(); List <double> Azimuth = new List <double>(); List <double> Altitude = new List <double>(); for (int i = 0; i < nvectores; i++) {//read each sample X.Add(reader.ReadSingle()); Y.Add(reader.ReadSingle()); Pressure.Add(reader.ReadSingle()); Azimuth.Add(reader.ReadSingle()); Altitude.Add(reader.ReadSingle()); } //set signature features signature.SetFeature(MCYT.X, X); signature.SetFeature(MCYT.Y, Y); signature.SetFeature(MCYT.Pressure, Pressure);//TODO: readme-bol feltetelezzuk, hogy ez a sorrend signature.SetFeature(MCYT.Azimuth, Azimuth); signature.SetFeature(MCYT.Altitude, Altitude); if (standardFeatures) { signature.SetFeature(Features.X, X); signature.SetFeature(Features.Y, Y); signature.SetFeature(Features.Pressure, Pressure); signature.SetFeature(Features.Azimuth, Azimuth); signature.SetFeature(Features.Altitude, Altitude); //Time nincs MCYT-ben, de tudjuk, hogy 100 samples / sec //nem kell svc-hez ragaszkodni.. pl adjuk meg millisec-ben, 0 tol kezdve List <double> Time = new List <double>(); for (int i = 0; i < X.Count; i++) { Time.Add(i * 10);//ms } signature.SetFeature(Features.T, Time); //Pendown sincs MCYT-ben, mindig lent van? Pressure alapjan lehetne egy threshold signature.SetFeature(Features.Button, Enumerable.Repeat(true, X.Count).ToList()); signature.CalculateStandardStatistics(); } }