diff --git a/ISCamRecorder/CvCamera.cs b/ISCamRecorder/CvCamera.cs index aef671e..7f5ec3c 100644 --- a/ISCamRecorder/CvCamera.cs +++ b/ISCamRecorder/CvCamera.cs @@ -6,15 +6,30 @@ using OpenCvSharp; using OpenCvSharp.Extensions; using System.Drawing; +using System.Diagnostics; +using System.IO; namespace ISCamRecorder { + struct FrameInfo { + public DateTime FrameTime { get; private set; } + public Mat FrameImage { get; private set; } + + public FrameInfo(Mat frame) { + FrameImage = frame; + FrameTime = DateTime.Now; + } + } + internal class CvCamera { VideoCapture camera = null; // カメラオブジェクト bool _ExitSignal = false; // 終了シグナル Bitmap[] _Buffer = new Bitmap[2]; // ダブルバッファ int _WriteBufferID = 0; // 書き込みバッファ番号 FrameRateCounter _Fps = new FrameRateCounter(10); // フレームレート計測 + bool _Recoding = false; // 録画中フラグ + List _RecFrames = new List(); // 録画画像 + string _OutputDir; /// /// カメラ接続 @@ -39,7 +54,9 @@ while (!_ExitSignal) { using (var frame = new Mat()) { camera.Read(frame); - //if (_Buffer[_WriteBufferID] != null) _Buffer[_WriteBufferID].Dispose(); + if (_Recoding) { + _RecFrames.Add(new FrameInfo(frame.Clone())); + } _Buffer[_WriteBufferID] = BitmapConverter.ToBitmap(frame); _WriteBufferID = 1 - _WriteBufferID; // バッファ切り替え _Fps.Shot(); @@ -47,15 +64,42 @@ } // 終了処理(メモリ解放) - //for (var i= 0; i < _Buffer.Length; i++) { - // if (_Buffer[i] != null) { - // _Buffer[i].Dispose(); - // _Buffer[i] = null; - // } - //} if (camera != null) camera.Dispose(); } + public void SaveToFile(string outDir, string imageType) { + var CamID = "CvCam"; + Debug.WriteLine($"{CamID} starts saving with 0.0fps."); + // 保存先確保 + var outDir2 = Path.Combine(outDir, CamID); + Directory.CreateDirectory(outDir2); + + for (int i = 0; i < _RecFrames.Count; i++) { + string strSampleTime = _RecFrames[i].FrameTime.ToString(@"HHmmss\.fff"); + var fileName = $"{CamID}_{strSampleTime}.{imageType.ToLower()}"; + var filePath = Path.Combine(outDir2, fileName); + _RecFrames[i].FrameImage.SaveImage(filePath); + } + + _RecFrames.Clear(); + Debug.WriteLine($"{CamID} ends saving."); + } + + /// + /// 録画開始 + /// + public void StartRecoding() { + if (_RecFrames.Count > 0) _RecFrames.Clear(); + _Recoding = true; + } + + /// + /// 録画中断 + /// + public void StopRecoding() { + _Recoding = false; + } + /// /// 撮影画像の取得 /// diff --git a/ISCamRecorder/ISCamera.cs b/ISCamRecorder/ISCamera.cs index 134aeaf..49d820b 100644 --- a/ISCamRecorder/ISCamera.cs +++ b/ISCamRecorder/ISCamera.cs @@ -136,8 +136,7 @@ for (int i = 0; i < _bufferlist.Length; i++) { writer.Write(_bufferlist[i]); var driverTime = _bufferlist[i].FrameMetadata.DriverFrameFirstPacketTime; - var frameTime = _RecodingBegin.Add(driverTime - firstDriverTime); - //このフレームの最初のパケットをドライバが受信した時刻が格納されます。 + var frameTime = _RecodingBegin.Add(driverTime - firstDriverTime); // パケットをドライバが受信した時刻 string strSampleTime = frameTime.ToString(@"HHmmss\.fff"); var fileName = $"{_CamID}_{strSampleTime}.{imageType.ToLower()}"; var filePath = Path.Combine(outDir2, fileName); diff --git a/ISCamRecorder/MainForm.cs b/ISCamRecorder/MainForm.cs index 0d1621b..3929f2c 100644 --- a/ISCamRecorder/MainForm.cs +++ b/ISCamRecorder/MainForm.cs @@ -267,6 +267,7 @@ var imageType = CboImageType.Text; var sensorFile = Path.Combine(outputDir, $"Sensor_{recTime}.csv"); _Sensor.StartRecoding(sensorFile); + _CvCamera.StartRecoding(); // 録画 Task[] tasks = new Task[4]; for (var i = 0; i < _Cameras.Count; i++) { @@ -275,6 +276,7 @@ } Task.WaitAll(tasks); _Sensor.StopRecoding(); + _CvCamera.StopRecoding(); // 保存 BtnRecodeMovie.Text = "保存中"; BtnRecodeMovie.BackColor = Color.Aqua; @@ -284,6 +286,7 @@ outputDir, frameRate, movieRate, imageType, recTime)); } Task.WaitAll(tasks); + _CvCamera.SaveToFile(outputDir, imageType); // プレビューモードへ変更 _Cameras.ForEach(c => c.ChangeSink(false));