diff --git a/EcomAnalysis/Form1.Designer.cs b/EcomAnalysis/Form1.Designer.cs index d9eea56..4d311dc 100644 --- a/EcomAnalysis/Form1.Designer.cs +++ b/EcomAnalysis/Form1.Designer.cs @@ -50,6 +50,9 @@ this.label10 = new System.Windows.Forms.Label(); this.TxtSubject = new System.Windows.Forms.TextBox(); this.label11 = new System.Windows.Forms.Label(); + this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader7 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader8 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.SuspendLayout(); // // label1 @@ -244,7 +247,10 @@ this.columnHeader2, this.columnHeader3, this.columnHeader4, - this.columnHeader5}); + this.columnHeader5, + this.columnHeader6, + this.columnHeader7, + this.columnHeader8}); this.listView1.Font = new System.Drawing.Font("MS UI Gothic", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); this.listView1.FullRowSelect = true; this.listView1.GridLines = true; @@ -264,25 +270,25 @@ // this.columnHeader2.Text = "FB回数"; this.columnHeader2.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; - this.columnHeader2.Width = 100; + this.columnHeader2.Width = 80; // // columnHeader3 // this.columnHeader3.Text = "EC時間"; this.columnHeader3.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; - this.columnHeader3.Width = 120; + this.columnHeader3.Width = 100; // // columnHeader4 // this.columnHeader4.Text = "潜時"; this.columnHeader4.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; - this.columnHeader4.Width = 120; + this.columnHeader4.Width = 100; // // columnHeader5 // this.columnHeader5.Text = "心拍数"; this.columnHeader5.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; - this.columnHeader5.Width = 120; + this.columnHeader5.Width = 100; // // label10 // @@ -316,6 +322,24 @@ this.label11.TabIndex = 19; this.label11.Text = "被験者"; // + // columnHeader6 + // + this.columnHeader6.Text = "瞬目回数"; + this.columnHeader6.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeader6.Width = 100; + // + // columnHeader7 + // + this.columnHeader7.Text = "瞳孔径:右"; + this.columnHeader7.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeader7.Width = 100; + // + // columnHeader8 + // + this.columnHeader8.Text = "瞳孔径:左"; + this.columnHeader8.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeader8.Width = 100; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); @@ -379,6 +403,9 @@ private System.Windows.Forms.Label label10; private System.Windows.Forms.TextBox TxtSubject; private System.Windows.Forms.Label label11; + private System.Windows.Forms.ColumnHeader columnHeader6; + private System.Windows.Forms.ColumnHeader columnHeader7; + private System.Windows.Forms.ColumnHeader columnHeader8; } } diff --git a/EcomAnalysis/Form1.cs b/EcomAnalysis/Form1.cs index 63f88ad..6f9ebda 100644 --- a/EcomAnalysis/Form1.cs +++ b/EcomAnalysis/Form1.cs @@ -14,7 +14,7 @@ public partial class Form1 : Form { private string[] _HeaderItems = { - "stimNo", "sceneNo", "stimTime", "contact time", "Feedback", "RR" }; + "stimNo", "sceneNo", "stimTime", "contact time", "Feedback", "RR", "gazeVx", "gazeVy", "pupilR", "pupilL" }; private Dictionary _SceneNoAssign = new Dictionary(); private List _Data = new List(); @@ -72,6 +72,7 @@ } // シーン別解析 + listView1.Items.Clear(); if (_Data.Where(s => s.SceneNo > 0).Count() > 0) { var sceneBegin = _Data.Where(s => s.SceneNo > 0).Min(s => s.SceneNo); var sceneEnd = _Data.Where(s => s.SceneNo > 0).Max(s => s.SceneNo); @@ -89,11 +90,15 @@ dat.Where(c => c.Feedback > 0).Select(s => s.SceneTime).First(); var validRR = dat.Where(s => s.RR >= RR_MIN && s.RR <= RR_MAX); scDat.Beat = validRR.Count() > 0 ? RR2HB / validRR.Select(s => s.RR).Average() : 0; + scDat.Blink = CountEyeBlink(dat); + scDat.Pupil.R = dat.Select(s => s.Pupil.R).Average(); + scDat.Pupil.L = dat.Select(s => s.Pupil.L).Average(); var items = new string[] { $"{scDat.SceneNo}", $"{scDat.FBCount} 回", $"{scDat.ECTime:0.00} 秒", $"{scDat.Latency:0.00} 秒", - $"{scDat.Beat:0.00} bpm" }; + $"{scDat.Beat:0.00} bpm", $"{scDat.Blink} 回", + $"{scDat.Pupil.R:0.00} mm", $"{scDat.Pupil.L:0.00} mm"}; listView1.Items.Add(new ListViewItem(items)); allData.Add(scDat); } @@ -107,7 +112,10 @@ $"{allData.Select(s=>s.FBCount).Average():0.00} 回", $"{allData.Select(s=>s.ECTime).Average():0.00} 秒", $"{meanLatency:0.00} 秒", - $"{meanBeat:0.00} bpm" })); + $"{meanBeat:0.00} bpm", + $"{allData.Select(s=>s.Blink).Average():0.00} 回", + $"{allData.Select(s=>s.Pupil.R).Average():0.00} ms", + $"{allData.Select(s=>s.Pupil.L).Average():0.00} ms"})); } // 表示 @@ -120,6 +128,28 @@ } /// + /// 瞬目回数を算出 + /// + /// 瞬目回数 + /// + private int CountEyeBlink(IEnumerable dat) { + const int BLINK_LENGTH = 4; // 瞬目と判断する視線データ未検出回数 + int close = 0; // 閉じている回数 + int blink = 0; // 瞬目回数 + + foreach (var d in dat.OrderBy(s => s.SceneTime)) { + if (d.GazeV.x < 0) { + ++close; + } else { + if (close >= BLINK_LENGTH) ++blink; + close = 0; + } + } + + return blink; + } + + /// /// CSVファイルの読み込み /// /// @@ -159,6 +189,10 @@ ld.RR = int.Parse(line[headerCol["RR"]]); ld.SceneNo = sceneNoExist ? int.Parse(line[headerCol["sceneNo"]]) : (_SceneNoAssign.ContainsKey(ld.StimNo) ? _SceneNoAssign[ld.StimNo] : 0); + ld.GazeV.x = float.Parse(line[headerCol["gazeVx"]]); + ld.GazeV.y = float.Parse(line[headerCol["gazeVy"]]); + ld.Pupil.R = float.Parse(line[headerCol["pupilR"]]); + ld.Pupil.L = float.Parse(line[headerCol["pupilL"]]); _Data.Add(ld); } //Debug.WriteLine(_Data.Count); diff --git a/EcomAnalysis/LogData.cs b/EcomAnalysis/LogData.cs index f9d3e0f..ad4ed9c 100644 --- a/EcomAnalysis/LogData.cs +++ b/EcomAnalysis/LogData.cs @@ -6,17 +6,22 @@ namespace EcomAnalysis { - //struct Point2f { - // public float x; - // public float y; - //} + struct Point2f { + public float x; + public float y; + } + + struct LR { + public float L; + public float R; + } class LogData { //public double ElapTime; // 経過時間 public int StimNo; // 刺激データ番号 public int SceneNo; // シーン番号 public double SceneTime; // 刺激提示の経過時間 - //public Point2f GazeV; // 注視点(視野カメラ座標) + public Point2f GazeV; // 注視点(視野カメラ座標) //public Point2f Shift; // ずれ //public Point2f GazeI; // 注視点(画像座標) //public int Target; // ターゲット判定 @@ -24,15 +29,16 @@ public int Feedback; // フィードバック //public int TrainingLevel; // トレーニングレベル public int RR; // バイタル出力(RR間隔) - //public float PupilL; // 瞳孔径 - //public float PupilR; // 瞳孔径 + public LR Pupil; // 瞳孔径 } class SceneData { public int SceneNo; public int FBCount; + public int Blink; public double ECTime; public double Latency; public double Beat; + public LR Pupil; } }