diff --git a/ISCamRecorder/App.config b/ISCamRecorder/App.config index 56efbc7..7d84477 100644 --- a/ISCamRecorder/App.config +++ b/ISCamRecorder/App.config @@ -1,6 +1,14 @@ - + + + + + + + + + \ No newline at end of file diff --git a/ISCamRecorder/CvCamera.cs b/ISCamRecorder/CvCamera.cs new file mode 100644 index 0000000..aef671e --- /dev/null +++ b/ISCamRecorder/CvCamera.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenCvSharp; +using OpenCvSharp.Extensions; +using System.Drawing; + +namespace ISCamRecorder { + + internal class CvCamera { + VideoCapture camera = null; // カメラオブジェクト + bool _ExitSignal = false; // 終了シグナル + Bitmap[] _Buffer = new Bitmap[2]; // ダブルバッファ + int _WriteBufferID = 0; // 書き込みバッファ番号 + FrameRateCounter _Fps = new FrameRateCounter(10); // フレームレート計測 + + /// + /// カメラ接続 + /// + /// + public bool Open() { + camera = new VideoCapture(0); + if (!camera.IsOpened()) { + camera.Dispose(); + camera = null; + return false; + } + + return true; + } + + /// + /// 撮影ループ + /// + public void CameraLoop() { + // 撮影ループ + while (!_ExitSignal) { + using (var frame = new Mat()) { + camera.Read(frame); + //if (_Buffer[_WriteBufferID] != null) _Buffer[_WriteBufferID].Dispose(); + _Buffer[_WriteBufferID] = BitmapConverter.ToBitmap(frame); + _WriteBufferID = 1 - _WriteBufferID; // バッファ切り替え + _Fps.Shot(); + } + } + + // 終了処理(メモリ解放) + //for (var i= 0; i < _Buffer.Length; i++) { + // if (_Buffer[i] != null) { + // _Buffer[i].Dispose(); + // _Buffer[i] = null; + // } + //} + if (camera != null) camera.Dispose(); + } + + /// + /// 撮影画像の取得 + /// + /// + public Bitmap GetImage() { + return _Buffer[1 - _WriteBufferID]; + } + + /// + /// 停止 + /// + public void Stop() { + _ExitSignal = true; + } + + /// + /// カメラ情報文字列 + /// + /// + public string CameraInfo() { + if (camera == null) return "接続中"; + return $"{camera.FrameWidth}x{camera.FrameHeight} {_Fps.FrameRate:0.0} fps"; + } + + /// + /// 1秒録画に要するメモリ量 + /// + /// + public float MemoryFor1SecRecoding() { + if (camera == null) return 0; + int frameSize = 3 * camera.FrameWidth * camera.FrameHeight; + int bcs = 1024 * 1024; + return _Fps.FrameRate * frameSize / bcs; + } + } +} diff --git a/ISCamRecorder/ISCamRecorder.csproj b/ISCamRecorder/ISCamRecorder.csproj index 2018da5..3e58cbc 100644 --- a/ISCamRecorder/ISCamRecorder.csproj +++ b/ISCamRecorder/ISCamRecorder.csproj @@ -1,5 +1,6 @@  + Debug @@ -12,6 +13,8 @@ 512 true true + + AnyCPU @@ -57,9 +60,31 @@ + + ..\packages\OpenCvSharp4.4.6.0.20220608\lib\netstandard2.0\OpenCvSharp.dll + + + ..\packages\OpenCvSharp4.Extensions.4.6.0.20220608\lib\netstandard2.0\OpenCvSharp.Extensions.dll + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\packages\System.Drawing.Common.5.0.3\lib\net461\System.Drawing.Common.dll + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + @@ -76,6 +101,7 @@ + @@ -114,6 +140,7 @@ True Resources.resx + SettingsSingleFileGenerator Settings.Designer.cs @@ -136,4 +163,10 @@ copy $(ProjectDir)*.iccf $(TargetDir) + + + このプロジェクトは、このコンピューター上にない NuGet パッケージを参照しています。それらのパッケージをダウンロードするには、[NuGet パッケージの復元] を使用します。詳細については、http://go.microsoft.com/fwlink/?LinkID=322105 を参照してください。見つからないファイルは {0} です。 + + + \ No newline at end of file diff --git a/ISCamRecorder/MainForm.Designer.cs b/ISCamRecorder/MainForm.Designer.cs index ee80fc8..6bcb7f1 100644 --- a/ISCamRecorder/MainForm.Designer.cs +++ b/ISCamRecorder/MainForm.Designer.cs @@ -59,11 +59,14 @@ this.label6 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label(); this.CboImageType = new System.Windows.Forms.ComboBox(); + this.PicCvCamera = new System.Windows.Forms.PictureBox(); + this.TxtCvCamera = new System.Windows.Forms.TextBox(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); + this.splitContainer2.Panel1.SuspendLayout(); this.splitContainer2.Panel2.SuspendLayout(); this.splitContainer2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).BeginInit(); @@ -83,6 +86,7 @@ this.splitContainer5.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.icFront)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.icRight)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PicCvCamera)).BeginInit(); this.SuspendLayout(); // // BtnSetProperty @@ -132,6 +136,11 @@ this.splitContainer2.Location = new System.Drawing.Point(0, 0); this.splitContainer2.Name = "splitContainer2"; // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.TxtCvCamera); + this.splitContainer2.Panel1.Controls.Add(this.PicCvCamera); + // // splitContainer2.Panel2 // this.splitContainer2.Panel2.Controls.Add(this.splitContainer3); @@ -498,6 +507,30 @@ this.CboImageType.TabIndex = 21; this.CboImageType.Text = "JPG"; // + // PicCvCamera + // + this.PicCvCamera.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.PicCvCamera.Location = new System.Drawing.Point(3, 28); + this.PicCvCamera.Name = "PicCvCamera"; + this.PicCvCamera.Size = new System.Drawing.Size(290, 218); + this.PicCvCamera.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.PicCvCamera.TabIndex = 0; + this.PicCvCamera.TabStop = false; + // + // TxtCvCamera + // + this.TxtCvCamera.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TxtCvCamera.BackColor = System.Drawing.Color.SkyBlue; + this.TxtCvCamera.Location = new System.Drawing.Point(3, 3); + this.TxtCvCamera.Name = "TxtCvCamera"; + this.TxtCvCamera.ReadOnly = true; + this.TxtCvCamera.Size = new System.Drawing.Size(290, 19); + this.TxtCvCamera.TabIndex = 3; + this.TxtCvCamera.Text = "追加カメラ"; + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); @@ -533,6 +566,8 @@ this.splitContainer1.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); + this.splitContainer2.Panel1.ResumeLayout(false); + this.splitContainer2.Panel1.PerformLayout(); this.splitContainer2.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); this.splitContainer2.ResumeLayout(false); @@ -558,6 +593,7 @@ this.splitContainer5.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.icFront)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.icRight)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PicCvCamera)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -597,6 +633,8 @@ private System.Windows.Forms.ComboBox CboImageType; private System.Windows.Forms.DataVisualization.Charting.Chart chart1; private System.Windows.Forms.TextBox TxtSensor; + private System.Windows.Forms.PictureBox PicCvCamera; + private System.Windows.Forms.TextBox TxtCvCamera; } } diff --git a/ISCamRecorder/MainForm.cs b/ISCamRecorder/MainForm.cs index 724080b..0d1621b 100644 --- a/ISCamRecorder/MainForm.cs +++ b/ISCamRecorder/MainForm.cs @@ -17,15 +17,19 @@ namespace ISCamRecorder { public partial class MainForm : Form { - readonly int PLOT_LENGTH = 200; - readonly int PLOT_YAXIS_MIN = 800; + readonly int PLOT_LENGTH = 200; // センサー値表示サンプル数 + readonly int PLOT_YAXIS_MIN = 800; // センサー値縦軸仮最小値 + readonly int PLOT_UPDATE_INTERVAL = 30; // グラフ更新時間 + readonly int UI_UPDATE_INTERVAL = 2000; // UI更新時間 private System.Threading.Timer _UITimer; // UI更新タイマー List _Cameras = new List (); // カメラオブジェクト SensorData _Sensor = new SensorData(); // センサーオブジェクト + CvCamera _CvCamera = new CvCamera (); bool _ExitSignal = false; // ソフトウェア終了シグナル Task _TriggerThread; // トリガースレッド Task _SerialThread; // シリアル通信スレッド + Task _CvCameraThread; // opencvカメラスレッド float _TriggerFrameRate = 30.0F; // トリガーフレームレート private ulong _availablePhysicalMemory; //合計物理メモリ DateTime _LastUpdate; // 前回のUI更新時間 @@ -54,9 +58,10 @@ _Cameras.ForEach(c => c.Connect()); // タイマー&スレッド起動 - _UITimer = new System.Threading.Timer(UITimerCB, this, 0, 30); + _UITimer = new System.Threading.Timer(UITimerCB, this, 0, PLOT_UPDATE_INTERVAL); _TriggerThread = Task.Run(TriggerThread); _SerialThread = Task.Run(SerialThread); + _CvCameraThread = Task.Run(CvCameraThread); _LastUpdate = DateTime.Now; } @@ -78,6 +83,14 @@ } /// + /// OpenCVカメラスレッド + /// + private void CvCameraThread() { + if (!_CvCamera.Open()) return; + _CvCamera.CameraLoop(); + } + + /// /// シリアル通信スレッド /// private void SerialThread() { @@ -97,6 +110,8 @@ chart1.ChartAreas[0].AxisY.Minimum = minValue < PLOT_YAXIS_MIN ? minValue : PLOT_YAXIS_MIN; } + + PicCvCamera.Image = _CvCamera.GetImage(); } /// @@ -113,13 +128,14 @@ public void UpdateForm() { var now = DateTime.Now; var elapsed = now - _LastUpdate; - if (elapsed.TotalSeconds > 2) { + if (elapsed.TotalMilliseconds > UI_UPDATE_INTERVAL) { _LastUpdate = now; TxtTop.Text = $"上方カメラ {_Cameras[0].CameraInfo()}"; TxtLeft.Text = $"左方カメラ {_Cameras[1].CameraInfo()}"; TxtFront.Text = $"前方カメラ {_Cameras[2].CameraInfo()}"; TxtRight.Text = $"右方カメラ {_Cameras[3].CameraInfo()}"; TxtSensor.Text = $"逆血センサー {_Sensor.FrameRate:0.0} Hz"; + TxtCvCamera.Text = $"追加カメラ {_CvCamera.CameraInfo()}"; TotalPhysicalMemory(); MemoryToUse(); _TriggerFrameRate = float.Parse(TxtTriggerFPS.Text); @@ -158,9 +174,11 @@ private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { _UITimer.Dispose(); _Sensor.Stop(); + _CvCamera.Stop(); _ExitSignal = true; _TriggerThread.Wait(); _SerialThread.Wait(); + _CvCameraThread.Wait(); } /// diff --git a/ISCamRecorder/packages.config b/ISCamRecorder/packages.config new file mode 100644 index 0000000..9cbf8ac --- /dev/null +++ b/ISCamRecorder/packages.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file