diff --git a/ISCamRecorder/CvCamera.cs b/ISCamRecorder/CvCamera.cs index 6c7035a..012cede 100644 --- a/ISCamRecorder/CvCamera.cs +++ b/ISCamRecorder/CvCamera.cs @@ -143,7 +143,11 @@ /// public string CameraInfo() { if (camera == null) return "接続中"; - return $"{camera.FrameWidth}x{camera.FrameHeight} {_Fps.FrameRate:0.0} fps"; + try { + return $"{camera.FrameWidth}x{camera.FrameHeight} {_Fps.FrameRate:0.0} fps"; + } catch (Exception _) { + return ""; + } } /// diff --git a/ISCamRecorder/MainForm.Designer.cs b/ISCamRecorder/MainForm.Designer.cs index fa3e59d..7a7c367 100644 --- a/ISCamRecorder/MainForm.Designer.cs +++ b/ISCamRecorder/MainForm.Designer.cs @@ -28,6 +28,7 @@ System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series(); System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series(); System.Windows.Forms.DataVisualization.Charting.Series series3 = new System.Windows.Forms.DataVisualization.Charting.Series(); + System.Windows.Forms.DataVisualization.Charting.Series series4 = new System.Windows.Forms.DataVisualization.Charting.Series(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.BtnSetProperty = new System.Windows.Forms.Button(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); @@ -256,7 +257,7 @@ series1.Color = System.Drawing.Color.Blue; series1.MarkerColor = System.Drawing.Color.Blue; series1.MarkerSize = 15; - series1.Name = "SeriesB"; + series1.Name = "B"; series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Single; series1.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; series2.BorderWidth = 3; @@ -265,19 +266,27 @@ series2.Color = System.Drawing.Color.Red; series2.MarkerColor = System.Drawing.Color.Red; series2.MarkerSize = 15; - series2.Name = "SeriesR"; + series2.Name = "R"; series2.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Single; series2.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; series3.BorderWidth = 3; series3.ChartArea = "ChartArea1"; series3.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine; series3.Color = System.Drawing.Color.Green; - series3.Name = "SeriesG"; + series3.Name = "G"; series3.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Single; series3.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; + series4.BorderWidth = 3; + series4.ChartArea = "ChartArea1"; + series4.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine; + series4.Color = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(0)))), ((int)(((byte)(192))))); + series4.Name = "Sat"; + series4.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Single; + series4.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; this.chart1.Series.Add(series1); this.chart1.Series.Add(series2); this.chart1.Series.Add(series3); + this.chart1.Series.Add(series4); this.chart1.Size = new System.Drawing.Size(337, 261); this.chart1.TabIndex = 0; this.chart1.Text = "chart1"; diff --git a/ISCamRecorder/MainForm.cs b/ISCamRecorder/MainForm.cs index dd3d226..6029cdd 100644 --- a/ISCamRecorder/MainForm.cs +++ b/ISCamRecorder/MainForm.cs @@ -154,7 +154,7 @@ TxtLeft.Text = $"左方カメラ {_Cameras[1].CameraInfo()}"; TxtFront.Text = $"前方カメラ {_Cameras[2].CameraInfo()}"; TxtRight.Text = $"右方カメラ {_Cameras[3].CameraInfo()}"; - TxtSensor.Text = $"逆血センサー {_Sensor.FrameRate:0.0} Hz"; + TxtSensor.Text = $"逆血センサー {_Sensor.FrameRate:0.0} Hz 検出対象:{Setting.RBDetectCh}"; TxtCvCamera.Text = $"追加カメラ {_CvCamera.CameraInfo()}"; if (State == STATE.Init && _CvCamera.CurrentFPS > 0) { State = STATE.Idle; diff --git a/ISCamRecorder/SensorData.cs b/ISCamRecorder/SensorData.cs index 783fa90..0fb31bd 100644 --- a/ISCamRecorder/SensorData.cs +++ b/ISCamRecorder/SensorData.cs @@ -21,9 +21,10 @@ readonly string SERIAL_PORT_NAME = "USB シリアル"; // デバイス名 readonly int NUM_SAMPLES_SET_THRES = 20; // 逆血検出閾値を決定するサンプル数(20Hz) SerialPort _Serial = null; // シリアル通信オブジェクト - Queue ValuesB = new Queue(); // センサー値 - Queue ValuesR = new Queue(); // センサー値 - Queue ValuesG = new Queue(); // センサー値 + Queue ValuesB = new Queue(); // センサー値R + Queue ValuesR = new Queue(); // センサー値G + Queue ValuesG = new Queue(); // センサー値B + Queue ValuesSat = new Queue(); // 彩度 Queue Times = new Queue(); // サンプル時間 int _QueueLength; // グラフ表示するサンプル数 StreamWriter _CsvWriter = null; // ファイル保存オブジェクト @@ -35,7 +36,6 @@ bool _ClearPlot = false; // プロット消去フラグ bool _IsReverseBlood = false; // 逆血フラグ int _ReverseBloodThreshold = -1; // 逆血検出閾値 - int _ReverseBloodCount = 0; // 逆血検出カウント public float FrameRate { get { return _Fps.FrameRate; } } // FPS値 @@ -87,8 +87,9 @@ /// 受信ループ /// public void Loop() { - while (_MF.State != STATE.Exit) { + var baseline = new float[] { 0, 0, 0 }; // ホワイトバランス用RGB基準値 + while (_MF.State != STATE.Exit) { // データ受信 var values = new int[] { 60, 80, 100, 20, 0 }; // センサー未接続時のダミー値 if (_Serial != null) { @@ -120,44 +121,66 @@ for (var i = 0; i < 4; i++) values[i] = int.Parse(items[i + 3]); } + // 彩度計算 + var sat = 0; + if (_ReverseBloodThreshold >= 0) { + var wbvals = new float[] { values[0] / baseline[0], values[1] / baseline[1], values[2] / baseline[2] }; + var vmax = wbvals.Max(); + var vmin = wbvals.Min(); + sat = (int)(1000F * (vmax - vmin) / vmax); + Debug.WriteLine($"{baseline[0]}, {baseline[1]}, {baseline[2]}, {vmax}, {vmin}, {sat}"); + } + // プロット追加 if (_ClearPlot) { _ClearPlot = false; ValuesB.Clear(); ValuesR.Clear(); ValuesG.Clear(); + ValuesSat.Clear(); Times.Clear(); } ValuesB.Enqueue(values[0]); ValuesR.Enqueue(values[1]); ValuesG.Enqueue(values[2]); + ValuesSat.Enqueue(sat); Times.Enqueue(elapsed / 1000F); while (ValuesB.Count > _QueueLength) { ValuesB.Dequeue(); ValuesR.Dequeue(); ValuesG.Dequeue(); + ValuesSat.Dequeue(); Times.Dequeue(); } + // 検出チャネル決定 + Queue detectCh; + switch (_MF.Setting.RBDetectCh) { + case "R": detectCh = ValuesR; break; + case "G": detectCh = ValuesG; break; + case "B": detectCh = ValuesB; break; + default: detectCh = ValuesSat; break; + } + // 逆血閾値決定 + var minValue = detectCh.Min(); + if (_ReverseBloodThreshold < 0 && detectCh.Count >= NUM_SAMPLES_SET_THRES) { + _ReverseBloodThreshold = _MF.Setting.RBDetectCh.Equals("Sat") ? _MF.Setting.RBThreshold : minValue - _MF.Setting.RBThreshold; + baseline[0] = (float)ValuesB.Average(); + baseline[1] = (float)ValuesR.Average(); + baseline[2] = (float)ValuesG.Average(); + //Debug.WriteLine($"逆血閾値 {_ReverseBloodThreshold} Baseline B,R,G={baseline[0]:0.0}, {baseline[1]:0.0}, {baseline[2]:0.0}"); + } + if (_IsRecoding) { - // 検出チャネル決定 - Queue detectCh; - switch (_MF.Setting.RBDetectCh) { - case "R": detectCh = ValuesR; break; - case "G": detectCh = ValuesG; break; - default: detectCh = ValuesB; break; - } - // 逆血閾値決定 - var minValue = detectCh.Min(); - if (_ReverseBloodThreshold < 0 && detectCh.Count >= NUM_SAMPLES_SET_THRES) { - _ReverseBloodThreshold = minValue - _MF.Setting.RBThreshold; - //Debug.WriteLine($"逆血閾値 {_ReverseBloodThreshold}"); - } // 逆血判定 - if (_ReverseBloodThreshold > 0) { - var count = detectCh.Skip(ValuesG.Count - _MF.Setting.RBDetectSize) - .Where(v => v <= _ReverseBloodThreshold).Count(); + if (_ReverseBloodThreshold >= 0) { + var detectData = detectCh.Skip(ValuesG.Count - _MF.Setting.RBDetectSize); + var count = 0; + if (_MF.Setting.RBDetectCh.Equals("Sat")) + count = detectData.Where(v => v >= _ReverseBloodThreshold).Count(); + else + count = detectData.Where(v => v <= _ReverseBloodThreshold).Count(); //Debug.WriteLine($"逆血検出数 {count}"); if (!_IsReverseBlood && count >= _MF.Setting.RBDetectCount) { _IsReverseBlood = true; @@ -174,12 +197,14 @@ // プロット表示 if (_MF.State != STATE.Exit) { _MF.SensorChart.Invoke((MethodInvoker)delegate { - _MF.SensorChart.Series[0].Points.Clear(); - if (_MF.Setting.RBDetectCh == "B") _MF.SensorChart.Series[0].Points.DataBindXY(Times, ValuesB); - _MF.SensorChart.Series[1].Points.Clear(); - if (_MF.Setting.RBDetectCh == "R") _MF.SensorChart.Series[1].Points.DataBindXY(Times, ValuesR); - _MF.SensorChart.Series[2].Points.Clear(); - if (_MF.Setting.RBDetectCh == "G") _MF.SensorChart.Series[2].Points.DataBindXY(Times, ValuesG); + foreach (var s in _MF.SensorChart.Series) { + s.Points.Clear(); + if (s.Name.Equals("B")) s.Points.DataBindXY(Times, ValuesB); + if (s.Name.Equals("G")) s.Points.DataBindXY(Times, ValuesG); + if (s.Name.Equals("R")) s.Points.DataBindXY(Times, ValuesR); + if (s.Name.Equals("Sat")) s.Points.DataBindXY(Times, ValuesSat); + s.BorderWidth = _MF.Setting.RBDetectCh.Equals(s.Name) ? 5 : 1; + } }); } @@ -216,7 +241,6 @@ _MF.SensorChart.Annotations["AnnReverseBlood"].Visible = true; }); _ReverseBloodThreshold = -1; - _ReverseBloodCount = 0; _IsReverseBlood = false; _ClearPlot = true; _IsRecoding = true; diff --git a/ISCamRecorder/Setting.Designer.cs b/ISCamRecorder/Setting.Designer.cs index 10c0d07..dde10d4 100644 --- a/ISCamRecorder/Setting.Designer.cs +++ b/ISCamRecorder/Setting.Designer.cs @@ -536,7 +536,7 @@ // label13 // this.label13.AutoSize = true; - this.label13.Location = new System.Drawing.Point(11, 27); + this.label13.Location = new System.Drawing.Point(11, 52); this.label13.Name = "label13"; this.label13.Size = new System.Drawing.Size(77, 12); this.label13.TabIndex = 35; @@ -544,9 +544,9 @@ // // TxtRBThreshold // - this.TxtRBThreshold.Location = new System.Drawing.Point(94, 24); + this.TxtRBThreshold.Location = new System.Drawing.Point(94, 49); this.TxtRBThreshold.Name = "TxtRBThreshold"; - this.TxtRBThreshold.Size = new System.Drawing.Size(25, 19); + this.TxtRBThreshold.Size = new System.Drawing.Size(33, 19); this.TxtRBThreshold.TabIndex = 58; this.TxtRBThreshold.Text = "10"; this.TxtRBThreshold.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; @@ -555,7 +555,7 @@ // label14 // this.label14.AutoSize = true; - this.label14.Location = new System.Drawing.Point(151, 27); + this.label14.Location = new System.Drawing.Point(151, 52); this.label14.Name = "label14"; this.label14.Size = new System.Drawing.Size(65, 12); this.label14.TabIndex = 59; @@ -563,7 +563,7 @@ // // TxtRBDetectSize // - this.TxtRBDetectSize.Location = new System.Drawing.Point(221, 24); + this.TxtRBDetectSize.Location = new System.Drawing.Point(221, 49); this.TxtRBDetectSize.Name = "TxtRBDetectSize"; this.TxtRBDetectSize.Size = new System.Drawing.Size(25, 19); this.TxtRBDetectSize.TabIndex = 60; @@ -574,7 +574,7 @@ // label15 // this.label15.AutoSize = true; - this.label15.Location = new System.Drawing.Point(250, 27); + this.label15.Location = new System.Drawing.Point(250, 52); this.label15.Name = "label15"; this.label15.Size = new System.Drawing.Size(29, 12); this.label15.TabIndex = 61; @@ -582,7 +582,7 @@ // // TxtRBDetectCount // - this.TxtRBDetectCount.Location = new System.Drawing.Point(282, 24); + this.TxtRBDetectCount.Location = new System.Drawing.Point(282, 49); this.TxtRBDetectCount.Name = "TxtRBDetectCount"; this.TxtRBDetectCount.Size = new System.Drawing.Size(25, 19); this.TxtRBDetectCount.TabIndex = 62; @@ -593,7 +593,7 @@ // label16 // this.label16.AutoSize = true; - this.label16.Location = new System.Drawing.Point(313, 27); + this.label16.Location = new System.Drawing.Point(313, 52); this.label16.Name = "label16"; this.label16.Size = new System.Drawing.Size(17, 12); this.label16.TabIndex = 63; @@ -624,16 +624,17 @@ this.CboRBDetectCh.Items.AddRange(new object[] { "R", "G", - "B"}); - this.CboRBDetectCh.Location = new System.Drawing.Point(83, 51); + "B", + "Sat"}); + this.CboRBDetectCh.Location = new System.Drawing.Point(83, 23); this.CboRBDetectCh.Name = "CboRBDetectCh"; - this.CboRBDetectCh.Size = new System.Drawing.Size(36, 20); + this.CboRBDetectCh.Size = new System.Drawing.Size(44, 20); this.CboRBDetectCh.TabIndex = 65; // // label17 // this.label17.AutoSize = true; - this.label17.Location = new System.Drawing.Point(11, 55); + this.label17.Location = new System.Drawing.Point(11, 27); this.label17.Name = "label17"; this.label17.Size = new System.Drawing.Size(66, 12); this.label17.TabIndex = 64; diff --git a/ISCamRecorder/Setting.cs b/ISCamRecorder/Setting.cs index ead7899..a589e7b 100644 --- a/ISCamRecorder/Setting.cs +++ b/ISCamRecorder/Setting.cs @@ -45,7 +45,7 @@ SWTriggerFPS = 40F; ButtonAction = ACTION.movie; SnapCameras = new bool[] { true, true, true, true, false }; - RBThreshold = 10; + RBThreshold = 100; RBDetectSize = 10; RBDetectCount = 5; RBDetectCh = "G";